Class: Istox::OrderBookPriceTime
- Inherits:
-
Object
- Object
- Istox::OrderBookPriceTime
- Defined in:
- lib/istox/helpers/order_book_price_time.rb
Class Method Summary collapse
- .allocation(soft_cap, total_supply, investments) ⇒ Object
-
.prorate_allocation(token_price, min_investment, bid_block, invest_step, hard_cap, interests) ⇒ Object
rubocop:disable Metrics/BlockNesting.
Class Method Details
.allocation(soft_cap, total_supply, investments) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/istox/helpers/order_book_price_time.rb', line 4 def allocation(soft_cap, total_supply, investments) # sort by token price desc, and id asc investments = investments.sort do |a, b| [b[:token_price], a[:id]] <=> [a[:token_price], b[:id]] end total_supply = ::BigDecimal.new(total_supply.to_s) interests = investments cutoff_price = 0.0 total_bid_token = 0.0 total_allocated = 0.0 total_unallocated = 0.0 total_investment = 0.0 cutoff_price = ::Istox::FMath.round_up(::Istox::FMath.div(soft_cap, total_supply), 2) is_cutoff = false # return result immediately if no interest unless interests.count.positive? return { total_supply: total_supply.to_s, total_investment: '0', cutoff_price: cutoff_price, total_bid_token: '0', total_allocated: '0', total_unallocated: total_supply.to_s, interests: [] } end interests = interests.map do |item| bid_token = Istox::FMath.round_down(::Istox::FMath.div(item[:fiat_amount], item[:token_price]), 0) total_bid_token = ::Istox::FMath.add(total_bid_token, bid_token) allocated = 0.0 unallocated = bid_token unless is_cutoff allocated = bid_token unallocated = 0.0 if ::BigDecimal.new(::Istox::FMath.add(total_allocated, bid_token)) >= total_supply unallocated = ::Istox::FMath.sub(::Istox::FMath.add(total_allocated, bid_token), total_supply) allocated = ::Istox::FMath.sub(bid_token, unallocated) cutoff_price = item[:token_price] is_cutoff = true end total_allocated = ::Istox::FMath.add(total_allocated, allocated) total_unallocated = ::Istox::FMath.add(total_unallocated, unallocated) end { id: item[:id], # user bidding total fiat amount fiat_amount: item[:fiat_amount], # user bidding price bid_price: item[:token_price], # total user bidding token derived from fiat_amount / token_price bid_token: bid_token, # round down allocated token to whole number allocated: ::Istox::FMath.round_down(allocated, 0), # round up unallocated token to whole number unallocated: ::Istox::FMath.round_up(unallocated, 0) } end interests = interests.map do |item| investment = ::Istox::FMath.mul(item[:allocated], cutoff_price) total_investment = ::Istox::FMath.add(total_investment, investment) # each user maximum total investment amount in fiat item.merge!(investment: investment) end { # total token supply total_supply: total_supply.to_s, # total investment in fiat total_investment: total_investment, # cut off price cutoff_price: cutoff_price.to_s, # total bid tokens, more than total supply for oversubscribe case total_bid_token: total_bid_token, # total allocated tokens total_allocated: total_allocated, # total unallocated tokens total_unallocated: total_unallocated, # all investor interest results interests: interests } end |
.prorate_allocation(token_price, min_investment, bid_block, invest_step, hard_cap, interests) ⇒ Object
rubocop:disable Metrics/BlockNesting
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/istox/helpers/order_book_price_time.rb', line 88 def prorate_allocation(token_price, min_investment, bid_block, invest_step, hard_cap, interests) # sort by id asc interests = interests.sort do |a, b| a[:id] <=> b[:id] end total_interests = 0 max_allowed_investor = Istox::FMath.round_down(::Istox::FMath.div( ::Istox::FMath.div(hard_cap, bid_block), token_price ), 0).to_i interests.each_with_index.map do |interest, i| total_interests = ::Istox::FMath.add(total_investment, interest.fiat_amount) if i < max_allowed_investor end # only need to handle when oversubscribe if total_interests.to_d > hard_cap.to_s.to_d # prorate the interests interests = interests.each_with_index.map do |interest, i| { id: interest.id, investment: i < max_allowed_investor ? ::FMath.mul(::FMath.div(interest.fiat_amount, total_interests), hard_cap) : '0' } end # do adjustments for interest if needed final_interests = interests.map do |interest| if interest[:investment].to_d < min_investment.to_d # calculate the adjusted amount lacking_amount = ::Istox::FMath.sub(min_investment, interest[:investment]) # if some investor has less than min_investment allocated, auto adjust to min investment interest[:investment] = min_investment.to_s # must deduct the adjust amount from later book building joiners who has more amount allocated # than min-investment if lacking_amount.to_d.positive? interests.reverse_each do |inner_interest| # skip the same interest from deduction candidate next unless inner_interest[:id] != interest[:id] # when investor investment is higher than min_investment, he will become a candidate to # get investment deduction while inner_interest[:investment].to_d > min_investment.to_d && lacking_amount.to_d.positive? lacking_amount = ::Istox::FMath.sub(lacking_amount, invest_step) inner_interest[:investment] = ::Istox::FMath.sub(inner_interest[:investment], invest_step) # add back the difference if over deduct an investor invest amount if lacking_amount.to_d.negative? inner_interest[:investment] = ::Istox::FMath.add(inner_interest[:investment], BigDecimal(lacking_amount).abs) end end end end end { id: interest[:id], investment: interest[:investment] } end else final_interests = interests.each_with_index.map do |interest, i| { id: interest.id, investment: i < max_allowed_investor ? interest.fiat_amount : '0' } end end { cutoff_price: token_price, interests: final_interests } end |