Boot Finance contest - gzeon's results

Custom DEX AMM for Defi Projects

General Information

Platform: Code4rena

Start Date: 04/11/2021

Pot Size: $50,000 USDC

Total HM: 20

Participants: 28

Period: 7 days

Judge: 0xean

Total Solo HM: 11

Id: 51

League: ETH

Boot Finance

Findings Distribution

Researcher Performance

Rank: 9/28

Findings: 2

Award: $1,311.11

🌟 Selected for report: 0

šŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: cmichel

Also found by: gzeon

Labels

bug
duplicate
3 (High Risk)

Awards

1308.4274 USDC - $1,308.43

External Links

Handle

gzeon

Vulnerability details

Impact

The custom swap curve depends on having 2 different A value, which is returned by determineA() function based on current price and _targetprice. _targetprice also change tokenPrecisionMultipliers which is used in the swap calculation. These behavior may lead to sub-optimal swap for the user when executing a large swap across _targetprice.

Proof of Concept

https://github.com/code-423n4/2021-11-bootfinance/blob/main/customswap/contracts/SwapUtils.sol L684

It is better for a user to break down a large swap to smaller swaps. Consider the following test case:

` it.only("Split trade return more", async () => {

const split = 4; const amtin = parseEther("10.0"); // User 1 calculates how much token to receive const calculatedSwapReturn = await swap.calculateSwap(0, 1, amtin) const [ tokenFromBalanceBefore, tokenToBalanceBefore, ] = await getUserTokenBalances(user1, [firstToken, secondToken]) // User 1 successfully initiates swap for (let index = 0; index < split; index++) { await swap .connect(user1) .swap(0, 1, amtin.div(split), 0, MAX_UINT256) } // Check the sent and received amounts are as expected const [ tokenFromBalanceAfter, tokenToBalanceAfter, ] = await getUserTokenBalances(user1, [firstToken, secondToken]) expect(tokenFromBalanceBefore.sub(tokenFromBalanceAfter)).to.eq( BigNumber.from(amtin), ) expect(tokenToBalanceAfter.sub(tokenToBalanceBefore)).to.gt( calculatedSwapReturn, ) console.log('got ' + tokenToBalanceAfter.sub(tokenToBalanceBefore).sub(calculatedSwapReturn).mul(1000000).div(calculatedSwapReturn).toNumber()/10000+'% more') })

`

Swap swap got 0.0943% more āœ“ Split trade return more (424ms)

1 passing (1s)

To optimize the swap, one should swap to the boundary and then swap the rest of the amount.

Tools Used

Hardhat

Remark

Similar idea might also allow one to manipulate price (sell) to the higher A region before doing a large buy to obtain a better rate. Honestly I just did a quick scan and don't quite get the math yet so I am not very sure about what is causing this. I have tried to change the A values but it doesn't seems to impact the % gain, however changing _targetPrice will lead to change in % of gain.

#0 - chickenpie347

2022-01-04T02:19:20Z

Duplicate of #216

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Ā© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter