Open hats-bug-reporter[bot] opened 1 month ago
Thank you for your submission.
- after calling math::rated_swap_to, there be fee amount of token left in the contract
- in self.mint_protocol_fee, only fee * self.protocol_fee / FEE_DENOM will be mint for fee receiver
That's correct and intentional. The (protocol)fee_receiver
gets its fee part in the form of LP token, just like the fee_receiver
would make a deposit of this protocol_fee
, without fee ofc. Before calculating the protocol_fee_lp
, the protocol_fee
is subtracted from the token_out
reserve, so the calculation of protocol_fee_lp
is fair.
- there will be fee - fee * self.protocol_fee / FEE_DENOM should mint for fee receiver.
The fee_receiver
will receive the protocol_fee_lp
amount of the LP token. The whole fee
amount will be left of the contract meaning that fee - protocol_fee
will contribute to the LP token value increase.
Github username: -- Twitter username: -- Submission hash (on-chain): 0xe3257595f501d3b1964e09e0def872e6caef397139449329b99075343e86fe71 Severity: high
Description: Description\ Since fee is charged in
swap_exact_in
swap_exact_out
swap_received
andadd_liquidity
remove_liquidity_by_amounts
, I will take lib._swap_exact_in as an example.In lib._swap_exact_in,
math::rated_swap_to
is called in lib.rs#L444-L452, andmath::rated_swap_to
is defined in mod.rs#L240-L264. Thenmod.swap_to
is called in mod.rs#L252-L259According to mod.swap_to, we can see that the amount of fee is calculated based on "token_out" amount, and the amount of output token is deducted the fee from mod.rs#L234-L237
Then back to
lib._swap_exact_in
, the contract callsdecrease_reserve
withdecrease_reserve
as input in lib.rs#L461, which means there willfee
amount oftoken_out
token left in contractAnd then
self.mint_protocol_fee
is called in lib.rs#L464According to lib.mint_protocol_fee
In lib.rs#L378, the fee is applied to
self.pool.fees.protocol_trade_fee
function again, and then the lp share is calculated based onprotocol_fee
in lib.rs#L387-L396And in lib.rs#L396,
protocol_fee_lp
is the final lp share the receiver can get, which isn't correct.Becase as we described in above:
fee
amount of token left in the contractfee * self.protocol_fee / FEE_DENOM
will be mint for fee receiverfee - fee * self.protocol_fee / FEE_DENOM
should mint for fee receiver.Attack Scenario\ Describe how the vulnerability can be exploited.
Attachments
Proof of Concept (PoC) File
Revised Code File (Optional)