Platform: Code4rena
Start Date: 03/10/2023
Pot Size: $24,500 USDC
Total HM: 6
Participants: 62
Period: 3 days
Judge: LSDan
Total Solo HM: 3
Id: 288
League: ETH
Rank: 52/62
Findings: 1
Award: $4.94
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0x3b, 0xAadi, 0xDING99YA, 0xTheC0der, 0xWaitress, 0xdice91, 100su, 3docSec, BRONZEDISC, BoRonGod, Eurovickk, GKBG, HChang26, IceBear, JP_Courses, MatricksDeCoder, Mike_Bello90, SovaSlava, Topmark, albahaca, cookedcookee, gzeon, hunter_w3b, kutugu, lukejohn, marqymarq10, matrix_0wl, orion, pep7siup, radev_sw, sces60107, taner2344, tpiliposian, wahedtalash77, xAriextz, zpan
4.9369 USDC - $4.94
https://github.com/code-423n4/2023-10-canto/tree/main/canto_ambient/contracts/mixins/LiquidityMining.sol#L193 https://github.com/code-423n4/2023-10-canto/tree/main/canto_ambient/contracts/mixins/LiquidityMining.sol#L286
The impact of this vulnerability is significant, as it can result in the loss of rewards for users who control owner contracts. If the owner input for the claimAmbientRewards
and claimConcentratedRewards
functions corresponds to a contract, it is possible that the owner contract does not, intentionally or unintentionally, implement the receive or fallback function in a way that supports receiving CANTO (the native token) or that calling the owner contract's receive or fallback function executes complicated logics that consume a substantial amount of gas. This could cause the call to claimAmbientRewards
or claimConcentratedRewards
to revert.
For example, if calling claimAmbientRewards
reverts due to issues in the owner contract, the owner contract would not be able to receive their eligible mining rewards. Consequently, the owner contract loses out on the rewards they rightfully deserve, which is unfair to the users who control it.
The root cause of the vulnerability is that the claimAmbientRewards
and claimConcentratedRewards
functions do not handle the scenario where the owner input corresponds to a contract that is unable to receive CANTO through its receive or fallback function. Let's walk through the issue with the following scenario:
Alice controls an owner contract that is designed to interact with the CrocSwapDex protocol.
Alice's owner contract does not implement the receive or fallback function properly to handle CANTO transfers.
Alice decides to call the claimAmbientRewards
function to claim her mining rewards from the Prime protocol.
The claimAmbientRewards
function attempts to transfer CANTO rewards to Alice's owner contract via the low-level owner.call
. Due to the improper implementation of the receive or fallback function in Alice's owner contract (OOG or lacking fallback/receive function), the transfer of CANTO reverts.
// File: canto_ambient/contracts/mixins/LiquidityMining.sol 256: function claimAmbientRewards( ... 285: if (rewardsToSend > 0) { 286: (bool sent, ) = owner.call{value: rewardsToSend}(""); // <= FOUND: will revert if owner is a contract that is unable to receive CANTO through its receive or fallback 287: require(sent, "Sending rewards failed"); 288: } 289: }
Manual Review
To mitigate this vulnerability, it is recommended to enhance the claimAmbientRewards
and claimConcentratedRewards
functions to handle cases where the owner input corresponds to a contract that may have limitations in receiving CANTO through its receive or fallback function. One possible approach is to use Wrapped CANTO (WCANTO) as an intermediary token to deposit the corresponding CANTO amount when calling these functions. The deposited WCANTO amount can then be transferred to the receiver contract, ensuring that rewards are not lost due to reverts.
Another approach could be introducing additional recipient
input as a dedicated address from the owner
to receive the CANTO rewards on their behalf.
call/delegatecall
#0 - c4-pre-sort
2023-10-08T09:46:05Z
141345 marked the issue as primary issue
#1 - 141345
2023-10-08T09:46:55Z
if the user intended to use contract to claim reward, some receive() function should be implemented, otherwise it's user's own mistake
#2 - c4-pre-sort
2023-10-09T16:36:20Z
141345 marked the issue as sufficient quality report
#3 - c4-sponsor
2023-10-11T10:42:02Z
OpenCoreCH (sponsor) disputed
#4 - c4-judge
2023-10-18T20:54:47Z
dmvt changed the severity to QA (Quality Assurance)
#5 - c4-judge
2023-10-18T22:34:16Z
dmvt marked the issue as grade-b