Platform: Code4rena
Start Date: 27/10/2022
Pot Size: $33,500 USDC
Total HM: 8
Participants: 96
Period: 3 days
Judge: kirk-baird
Total Solo HM: 1
Id: 176
League: ETH
Rank: 51/96
Findings: 2
Award: $29.55
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: ladboy233
Also found by: 0x52, 0xDecorativePineapple, 0xhunter, Aymen0909, Bnke0x0, Dravee, JTJabba, Jeiwan, Lambda, Nyx, Picodes, Trust, cccz, cryptonue, csanuragjain, dic0de, hansfriese, horsefacts, imare, minhtrng, pashov, peritoflores, rbserver, rvierdiiev, wagmi, yixxas
9.9073 USDC - $9.91
https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L653
The recoverERC20 function restricts owner from recovering reward tokens which are in use by contract. However the owner can simply bypass this by using removeRewardToken which will remove the Reward token from usage and allow admin to steal these funds
function recoverERC20(address token) external onlyOwner returns(bool) { if(minAmountRewardToken[token] != 0) revert Errors.CannotRecoverToken(); ... }
function removeRewardToken(address token) external onlyOwner { if(token == address(0)) revert Errors.ZeroAddress(); if(minAmountRewardToken[token] == 0) revert Errors.NotAllowedToken(); minAmountRewardToken[token] = 0; emit RemoveRewardToken(token); }
This sets minAmountRewardToken[Y] = 0;
Now owner can simply call recoverERC20 function and steal away all token Y funds
Place all owner functions behind a Timelock which will sufficient time to contract users to prevent their funds
#0 - Kogaroshi
2022-10-30T22:47:39Z
Duplicate of #17
#1 - c4-judge
2022-11-10T07:51:56Z
kirk-baird marked the issue as not a duplicate
#2 - c4-judge
2022-11-10T07:52:03Z
kirk-baird marked the issue as duplicate
#3 - c4-judge
2022-11-10T21:27:46Z
kirk-baird marked the issue as satisfactory
#4 - c4-judge
2022-11-10T21:27:55Z
kirk-baird marked the issue as not a duplicate
#5 - c4-judge
2022-11-10T21:28:04Z
kirk-baird marked the issue as duplicate of #17
#6 - c4-judge
2022-12-06T17:32:42Z
Simon-Busch marked the issue as duplicate of #68
🌟 Selected for report: robee
Also found by: 0x007, 0x1f8b, 0x52, 0xDjango, 0xNazgul, 0xSmartContract, 8olidity, Awesome, B2, Bnke0x0, Chom, Diana, Dravee, JTJabba, Jeiwan, Josiah, Lambda, Mathieu, Picodes, RaoulSchaffranek, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Ruhum, Sm4rty, Tricko, Trust, Waze, __141345__, a12jmx, adriro, ajtra, brgltd, c3phas, carlitox477, cccz, ch0bu, chaduke, chrisdior4, corerouter, cryptonue, csanuragjain, ctf_sec, cylzxje, delfin454000, dic0de, djxploit, horsefacts, imare, jayphbee, jwood, ktg, ladboy233, leosathya, lukris02, minhtrng, neko_nyaa, oyc_109, pashov, peritoflores, rbserver, rvierdiiev, shark, tnevler, yixxas
19.6449 USDC - $19.64
https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L438 https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L333
The contract is not handling fee on transfer token properly. This can lead to disastrous consequences including stealing from other users pledge reward token, User unable to retrieve their reward tokens as shown in POC
vars.totalRewardAmount = (rewardPerVote * vars.votesDifference * vars.duration) / UNIT; vars.feeAmount = (vars.totalRewardAmount * protocalFeeRatio) / MAX_PCT ; if(vars.totalRewardAmount > maxTotalRewardAmount) revert Errors.IncorrectMaxTotalRewardAmount(); if(vars.feeAmount > maxFeeAmount) revert Errors.IncorrectMaxFeeAmount(); // Pull all the rewards in this contract IERC20(rewardToken).safeTransferFrom(creator, address(this), vars.totalRewardAmount); // And transfer the fees from the Pledge creator to the Chest contract IERC20(rewardToken).safeTransferFrom(creator, chestAddress, vars.feeAmount);
Pledge User 1: pledgeAvailableRewardAmounts[User X Pledge id]=1000 Pledge User 2: pledgeAvailableRewardAmounts[User Y Pledge id]=2000 Contract Balance for Token T: 900+1800=2700
IERC20(pledgeParams.rewardToken).safeTransfer(receiver, remainingAmount);
Now remaining balance left in contract for this token T is 2700-2000=700
User X tries to close pledge but it fails since contract does not have sufficient funds left
pledgeAvailableRewardAmounts[User X Pledge id]=1000 Contract Balance for Token T:700
Calculate the contract balance before and after transfer to calculate the exact amount transferred to the contract. This way pledgeAvailableRewardAmounts will be updated correctly
#0 - Kogaroshi
2022-10-30T22:46:08Z
The issue with this type of tokens (and with rebasing tokens) are known, and are the reason why the Pledge contract only accepts tokens that are added to a whitelist (with addRewardToken) as valid tokens to be used for rewards, to prevent any issue when transferring reward tokens. The process to grant the whitelisted status to a token will have to be trusted to the Core team in the beginning, and later on by the Paladin Governance, to make the necessary verifications for each token before adding it the the list.
#1 - c4-judge
2022-11-10T07:21:58Z
kirk-baird marked the issue as primary issue
#2 - kirk-baird
2022-11-10T07:29:06Z
I'm going to consider FoT tokens to be a QA issue since there is whitelisting functionality which would reduce the likelihood of FoT being added and causing disruption to the protocol.
#3 - c4-judge
2022-11-10T07:29:23Z
kirk-baird changed the severity to QA (Quality Assurance)
#4 - c4-judge
2022-11-11T23:42:10Z
kirk-baird marked the issue as grade-b