Skip to content

Commit 415e9df

Browse files
committed
Account approximate_amount in available_funds after withdrawal
1 parent 83319b6 commit 415e9df

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

contracts/pool.func

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ int muldiv_extra(int a, int b, int c) inline {
202202
total_balance -= approximate_amount;
203203
supply -= jetton_amount;
204204
raw_reserve(balance - msg_value - approximate_amount - sent_during_rotation, 0);
205+
available_funds -= approximate_amount;
205206
var msg = begin_cell()
206207
.store_msg_flags(msgflag::NON_BOUNCEABLE)
207208
.store_slice(from_address)
@@ -217,10 +218,17 @@ int muldiv_extra(int a, int b, int c) inline {
217218
}
218219
;; conservatively use `borrowed` instead of `expected` as amount that will be returned
219220
var [_, _, _, borrowed, _, _, _] = prev_round_borrowers;
220-
int funds_at_round_end = available_funds + borrowed - FINALIZE_ROUND_FEE;
221+
222+
;; max(*, 0) is needed because optimistic withdrawals do not participate in sharing -FINALIZE_ROUND_FEE
223+
;; When we have both optimistic and pessimistic withdrawals it is ok: pessimists will get both
224+
;; FINALIZE_ROUND_FEE loss and pool round profit. The only problem is when optimists withdraw 100% value
225+
;; and there is no profit to cover FINALIZE_ROUND_FEE. In this case available_funds may become negative
226+
;; and max(*,0) helps with that
227+
228+
int funds_at_round_end = max(available_funds + borrowed - FINALIZE_ROUND_FEE, 0);
221229
(int projected_balance, int projected_supply) = _get_projected_conversion_ratio ();
222-
throw_unless( 100,
223-
funds_at_round_end > muldiv_extra(requested_for_withdrawal, projected_balance, projected_supply));
230+
throw_unless( 100, ;; error_code doesn't matter it will be catched
231+
funds_at_round_end >= muldiv_extra(requested_for_withdrawal, projected_balance, projected_supply));
224232
} catch (exc_arg, exc_num) {
225233
;; note that sent_during_rotation is null because
226234
;; effect of update_round is reverted in catch

0 commit comments

Comments
 (0)