contracts/arisen.system/src/com.cpp
/**
    * @brief Processes a sellcom order and returns object containing the results
    *
    * Processes an incoming or already scheduled sellcom order. If COM pool has enough core
    * tokens not frozen in loans, order is filled. In this case, COM pool totals, user com_balance
    * and user vote_stake are updated. However, this function does not update user voting power. The
    * function returns success flag, order proceeds, and vote stake delta. These are used later in a
    * different function to complete order processing, i.e. transfer proceeds to user COM fund and
    * update user vote weight.
    *
    * @param bitr - iterator pointing to com_balance database record
    * @param com - amount of com to be sold
    *
    * @return com_order_outcome - a struct containing success flag, order proceeds, and resultant
    * vote stake change
    */
@brief Processes a sellcom order and returns object containing the results
Processes an incoming or already scheduled sellcom order. If COM pool has enough core
tokens not frozen in loans, order is filled. In this case, COM pool totals, user com_balance
and user vote_stake are updated. However, this function does not update user voting power. The
function returns success flag, order proceeds, and vote stake delta. These are used later in a
different function to complete order processing, i.e. transfer proceeds to user COM fund and
update user vote weight.

@param bitr - iterator pointing to com_balance database record
@param com - amount of com to be sold

@return com_order_outcome - a struct containing success flag, order proceeds, and resultant
vote stake change
@brief Processes a sellcom order and returns object containing the results Processes an incoming or already scheduled sellcom order . If COM pool has enough core tokens not frozen in loans order is filled . In this case COM pool totals user com_balance and user vote_stake are updated . However this function does not update user voting power . The function returns success flag order proceeds and vote stake delta . These are used later in a different function to complete order processing i . e . transfer proceeds to user COM fund and update user vote weight . @param bitr - iterator pointing to com_balance database record @param com - amount of com to be sold @return com_order_outcome - a struct containing success flag order proceeds and resultant vote stake change
com_order_outcome system_contract::fill_com_order( const com_balance_table::const_iterator& bitr, const asset& com )
   {
      auto comitr = _compool.begin();
      const int64_t S0 = comitr->total_lendable.amount;
      const int64_t R0 = comitr->total_com.amount;
      const int64_t p  = (uint128_t(com.amount) * S0) / R0;
      const int64_t R1 = R0 - com.amount;
      const int64_t S1 = S0 - p;
      asset proceeds( p, core_symbol() );
      asset stake_change( 0, core_symbol() );
      bool  success = false;
      const int64_t unlent_lower_bound = ( uint128_t(2) * comitr->total_lent.amount ) / 10;
      const int64_t available_unlent   = comitr->total_unlent.amount - unlent_lower_bound; 
      if ( proceeds.amount <= available_unlent ) {
         const int64_t init_vote_stake_amount = bitr->vote_stake.amount;
         const int64_t current_stake_value    = ( uint128_t(bitr->com_balance.amount) * S0 ) / R0;
         _compool.modify( comitr, same_payer, [&]( auto& rt ) {
            rt.total_com.amount      = R1;
            rt.total_lendable.amount = S1;
            rt.total_unlent.amount   = rt.total_lendable.amount - rt.total_lent.amount;
         });
         _combalance.modify( bitr, same_payer, [&]( auto& rb ) {
            rb.vote_stake.amount   = current_stake_value - proceeds.amount;
            rb.com_balance.amount -= com.amount;
            rb.matured_com        -= com.amount;
         });
         stake_change.amount = bitr->vote_stake.amount - init_vote_stake_amount;
         success = true;
      } else {
         proceeds.amount = 0;
      }
      return { success, proceeds, stake_change };
   }
com_order_outcome system_contract :: fill_com_order ( const com_balance_table :: const_iterator & bitr , const asset & com ) { auto comitr = _compool . begin ( ) ; const int64_t S0 = comitr -> total_lendable . amount ; const int64_t R0 = comitr -> total_com . amount ; const int64_t p = ( uint128_t ( com . amount ) * S0 ) / R0 ; const int64_t R1 = R0 - com . amount ; const int64_t S1 = S0 - p ; asset proceeds ( p , core_symbol ( ) ) ; asset stake_change ( 0 , core_symbol ( ) ) ; bool success = false ; const int64_t unlent_lower_bound = ( uint128_t ( 2 ) * comitr -> total_lent . amount ) / 10 ; const int64_t available_unlent = comitr -> total_unlent . amount - unlent_lower_bound ; if ( proceeds . amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr -> vote_stake . amount ; const int64_t current_stake_value = ( uint128_t ( bitr -> com_balance . amount ) * S0 ) / R0 ; _compool . modify ( comitr , same_payer , [ & ] ( auto & rt ) { rt . total_com . amount = R1 ; rt . total_lendable . amount = S1 ; rt . total_unlent . amount = rt . total_lendable . amount - rt . total_lent . amount ; } ) ; _combalance . modify ( bitr , same_payer , [ & ] ( auto & rb ) { rb . vote_stake . amount = current_stake_value - proceeds . amount ; rb . com_balance . amount -= com . amount ; rb . matured_com -= com . amount ; } ) ; stake_change . amount = bitr -> vote_stake . amount - init_vote_stake_amount ; success = true ; } else { proceeds . amount = 0 ; } return { success , proceeds , stake_change } ; }
@brief Processes a sellcom order and returns object containing the results
 Processes an incoming or already scheduled sellcom order.
@brief Processes a sellcom order and returns object containing the results Processes an incoming or already scheduled sellcom order .
// available_unlent <= 0 is possible