Description:Description\
LP fees are neither correctly calculated nor stored when swapping tokens via StableSwapTwoPool::exchange
Attack Scenario\
LP providers earn fees when Thorn exchange sells tokens to swapping customers. The function responsible for swapping, StableSwapTwoPool::exchange, does not correctly calculate LP fee and neither does it provide a mechanism to store this value.
Attachments
Proof of Concept (PoC) File
Consider the fee calucation via StableSwapTwoPool::exchange:
uint256 dy = xp[j] - y - 1; // -1 just in case there were some rounding errors 1e18 * (10**(18 - coinDecimal) ) - y - 1
uint256 dy_fee = (dy * fee) / FEE_DENOMINATOR;
// Convert all to real units
dy = ((dy - dy_fee) * PRECISION) / RATES[j];// * 1e18 / (bal * (10**(18 - coinDecimal) );)
require(dy >= min_dy, "Exchange resulted in fewer coins than expected");
uint256 dy_admin_fee = (dy_fee * admin_fee) / FEE_DENOMINATOR;
dy_admin_fee = (dy_admin_fee * PRECISION) / RATES[j];
// Change balances exactly in same way as we change actual ERC20 coin amounts
balances[i] = old_balances[i] + dx;
// When rounding errors happen, we undercharge admin fee in favor of LP
balances[j] = old_balances[j] - dy - dy_admin_fee;
address iAddress = coins[i];
if (iAddress == ROSE_ADDRESS) {
require(dx == msg.value, "Inconsistent quantity");
} else {
IERC20(iAddress).safeTransferFrom(msg.sender, address(this), dx);
}
address jAddress = coins[j];
transfer_out(jAddress, dy);
emit TokenExchange(msg.sender, i, dx, j, dy);
There's no place where this fee is calculated nor saved in storage.
Revised Code File (Optional)
Consider providing a storage variable for storing calculated LP fee
Github username: -- Twitter username: -- Submission hash (on-chain): 0x3d426b4bbd2ae2007faae7ac4b9bee04bae2396d6d4533ad7cc74350bcee45f8 Severity: high
Description: Description\ LP fees are neither correctly calculated nor stored when swapping tokens via StableSwapTwoPool::exchange
Attack Scenario\ LP providers earn fees when Thorn exchange sells tokens to swapping customers. The function responsible for swapping, StableSwapTwoPool::exchange, does not correctly calculate LP fee and neither does it provide a mechanism to store this value. Attachments
There's no place where this fee is calculated nor saved in storage.