
When any user adds maker liquidity (via newMaker or adjustMaker), the amounts of token0 and token1 required from the user are calculated in the data.xBalance and data.yBalance, however the actual amounts spent to mint the required liquidity are never checked, the contract simply sends whatever amounts of both tokens are given by the uniswap pool in the mint callback. When the funds are settled for the maker liquidity change, the following functions are called:

This allows the user to manipulate the uniswap pool spot price to a different value via the RFTLib callback. PoolWalker.settle will then proceed to mint the required liquidity, but will use amounts of token0 and token1 different from the ones calculated and received from the user. Moreover, the total value of these tokens will always be higher than the value of tokens received from the user. When user manipulates the price back to initial value, he will have profit from this manipulation, stealing token0 and/or token1 from the contract.
As the contract uses Diamond proxy, this contract holds all token balances at the same address which is used to mint uniswap liquidity. In particular, the following funds are under risk:
- All Takers collateral
- All fees collected from the uniswap pool
Alpha: note how this is only possible because there is a central entity holding all the funds (diamond), always make sure to thing the attack through. Always make sure to check if changing pool spot price can lead to more funds for the attacker.
Weaponizing it
Note: a0 is used for amount of token0, a1 for amount of token1
1. Current price = 100;
2. Takers have a total collateral of 100 a0 and 10000 a1 (these are contract balances);
3. There is liquidity of 1 in the range [100;10000];
4. Attacker adds 111 maker liquidity in the range [100;10000], paying 10 a0;
5. In the RFTLib.settle attacker manipulates the price to 10000:
5.1. Attacker pays a1: -90;
5.2. Attacker receives a0: +0.09;
6. Attacker returns from the RFTLib callback, 111 liquidity is minted to Amplify, taking 10000 a1 from it;
7. Attacker manipulates the price back to 100:
6.1. Attacker pays a0: -10;
6.2. Attacker receives a1: +10000;
8. Attacker waits for jit penalty time to pass and withdraws his 111 maker liquidity, receiving 10 a0;
Contract balances:
• before: 100 a0 + 10000 a1 = $20000
• after: 110 a0 + 0 a1 = $11000
Attacker balances:
• a0: -10 + 0.09 - 10 + 10 = -9.91 [- $991]
• a1: -90 + 10000 = +9910 [+ $9910]
• uniswap manipulation fees (0.3%): (90 + 10000) * 0.003 = -30
Total : 9910 - 991 - 30 = +$8889
Conclusion
This finding would earn you $4432, and is quite elaborate, always make sure that it is safe to fetch the current reserves / spot price of an integrated Uniswap pool.