Platform: Code4rena
Start Date: 21/11/2022
Pot Size: $90,500 USDC
Total HM: 18
Participants: 101
Period: 7 days
Judge: Picodes
Total Solo HM: 4
Id: 183
League: ETH
Rank: 51/101
Findings: 2
Award: $74.20
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: deliriusz
Also found by: 0x52, 0xLad, 0xbepresent, Englave, R2, Ruhum, cccz, gzeon, hihen, keccak123, ladboy233, pashov, pedroais, perseverancesuccess, rbserver, rvierdiiev, simon135, unforgiven, wagmi, xiaoming90
20.7081 USDC - $20.71
https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/AutoPxGlp.sol#L210 https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/PirexGmx.sol#L497-L516
Compounded assets may be lost because AutoPxGlp::compound
can be called by anyone and minimum amount of Glp and USDG are under caller's control. The only check concerning minValues is that they are not zero (1 will work, however from the perspective of real tokens e.g. 1e6, or 1e18 it's virtually zero). Additionally, internal smart contract functions use it as well with minimal possible value (e.g. beforeDeposit
function)
compound
function calls PirexGmx::depositGlp, that uses external GMX reward router to mint and stake GLP.
https://snowtrace.io/address/0x82147c5a7e850ea4e28155df107f2590fd4ba327#code
141: function mintAndStakeGlpETH(uint256 _minUsdg, uint256 _minGlp) external payable nonReentrant returns (uint256) { ... 148: uint256 glpAmount = IGlpManager(glpManager).addLiquidityForAccount(address(this), account, weth, msg.value, _minUsdg, _minGlp);
Next GlpManager::addLiquidityForAccount
is called
https://github.com/gmx-io/gmx-contracts/blob/master/contracts/core/GlpManager.sol#L103
function addLiquidityForAccount(address _fundingAccount, address _account, address _token, uint256 _amount, uint256 _minUsdg, uint256 _minGlp) external override nonReentrant returns (uint256) { _validateHandler(); return _addLiquidity(_fundingAccount, _account, _token, _amount, _minUsdg, _minGlp); }
which in turn uses vault to swap token for specific amount of USDG before adding liquidity: https://github.com/gmx-io/gmx-contracts/blob/master/contracts/core/GlpManager.sol#L217
The amount of USGD to mint is calcualted by GMX own price feed: https://github.com/gmx-io/gmx-contracts/blob/master/contracts/core/Vault.sol#L765-L767
In times of market turbulence, or price oracle manipulation, all compound value may be lost
VS Code, arbiscan.io
Don't depend on user passing minimum amounts of usdg and glp tokens. Use GMX oracle to get current price, and additionally check it against some other price feed (e.g. ChainLink)
#0 - c4-judge
2022-12-04T12:28:34Z
Picodes marked the issue as duplicate of #183
#1 - c4-judge
2022-12-30T20:53:41Z
Picodes marked the issue as duplicate of #185
#2 - c4-judge
2022-12-30T21:05:20Z
Picodes marked the issue as selected for report
#3 - C4-Staff
2023-01-10T22:09:22Z
JeeberC4 marked the issue as not a duplicate
#4 - C4-Staff
2023-01-10T22:09:37Z
JeeberC4 marked the issue as primary issue
#5 - kphed
2023-01-25T18:50:07Z
We're using the following combination of mechanics in order to make it front-running compound
calls economically unattractive (or, at the very least, minimally impactful) for would-be attackers:
Both will result in a higher frequency of the vault compounding its rewards and less resources available for potential attackers.
🌟 Selected for report: 0xSmartContract
Also found by: 0xAgro, 0xNazgul, 0xPanda, 0xbepresent, 0xfuje, Awesome, B2, Bnke0x0, Deivitto, Diana, Funen, Jeiwan, JohnSmith, Josiah, R2, RaymondFam, Rolezn, Sathish9098, Waze, adriro, aphak5010, brgltd, btk, carrotsmuggler, ch0bu, chaduke, codeislight, codexploder, cryptostellar5, csanuragjain, danyams, datapunk, delfin454000, deliriusz, eierina, erictee, fatherOfBlocks, gz627, gzeon, hansfriese, hihen, jadezti, joestakey, keccak123, martin, nameruse, oyc_109, pedr02b2, perseverancesuccess, rbserver, rotcivegaf, rvierdiiev, sakshamguruji, shark, simon135, subtle77, unforgiven, xiaoming90, yixxas
53.4851 USDC - $53.49
There is double SafeTransferLib import in AutoPxGlp https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/AutoPxGlp.sol#L6-L8
AutoPxGlp::setPlatform
should be checked for being a contract and ideally if supports specific interface (EIP165). This contract is crucial to AutoPxGlp, so additional care should be put into making sure taht changing it won't break anything.
https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/AutoPxGlp.sol#L130
PxGmxReward
refers to a function that it does not implement
https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/PxGmxReward.sol#L72
PxGmxReward contract is not an ERC20, nor does it implement balanceOf
function.
Because of that lastBalance always will be 0, hence userRewardStates[user].rewards will always be zero,
which leads to user loosing all the funds deposited to this contract. Of course at the moment only AutoPxGlp uses this
contract, and it does implement ERC20, but it can lead to serious problems when used by itself/inherited from
some other contract.
72: uint256 balance = ERC20(address(this)).balanceOf(user);
Mitigation: It should be at least clearly stated in the documentation that this contract is not meant to be used by itself, or possibly checked if class that inherits from it supportsInterface ERC20 (ERC165), or PxGmxReward should implement ERC20 itself
#0 - c4-judge
2022-12-05T09:08:18Z
Picodes marked the issue as grade-b