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: 6/96
Findings: 3
Award: $1,308.38
🌟 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
When a user creates a new Pledge, the contract transfers the reward amount of rewardToken
from his address to the contract’s address. The issue is that the contract allows the contract’s owner to just transfer those rewardTokens
to himself anytime without having to delegate any boost to the Pledge creator.
Steps:
rewardToken
are transferred from his wallet to the contractremoveRewardToken
to set minAmountRewardToken[token] **=** *0*
recoverERC20
with the address of the rewardToken
rewardToken
are in the owner’s wallet, without him joining the pledge and delegating any boost, while the contract is left with 0 rewardToken
and no one can join that particular pledge anymoreThis gives 100% power of the admin to steal any user’s “pledged” reward tokens any time. This can happen not only with a compromised owner wallet but with an owner that turned malicious also.
Remove the recoverERC20 functionality, since it is not needed for the protocol’s functionality and is only there to “Recovers ERC2O tokens sent by mistake to the contract”
#0 - Kogaroshi
2022-10-30T23:38:16Z
Duplicate of #17
#1 - c4-judge
2022-11-10T07:12:56Z
kirk-baird marked the issue as not a duplicate
#2 - c4-judge
2022-11-10T07:13:04Z
kirk-baird marked the issue as duplicate
#3 - c4-judge
2022-11-10T21:23:05Z
kirk-baird marked the issue as satisfactory
#4 - c4-judge
2022-11-10T21:23:09Z
kirk-baird marked the issue as not a duplicate
#5 - c4-judge
2022-11-10T21:23:15Z
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
1117.8296 USDC - $1,117.83
Judge has assessed an item in Issue #107 as M risk. The relevant finding follows:
L-01 WardenPledge inherits Ownable instead of Owner https://github.com/code-423n4/2022-10-paladin/blob/66f9fcc813e220906a13e779b3198891e30459cc/contracts/WardenPledge.sol#L18 The contract imports Owner.sol but inherits Ownable - should both import and inherit Owner
#0 - c4-judge
2022-11-12T00:12:01Z
kirk-baird marked the issue as satisfactory
#1 - c4-judge
2022-11-12T00:13:12Z
kirk-baird marked the issue as duplicate of #161
🌟 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
180.6401 USDC - $180.64
WardenPledge
inherits Ownable instead of OwnerThe contract imports Owner.sol
but inherits Ownable
- should both import and inherit Owner
Ownable2Step
instead of inheriting from your own implementation for a 2 step ownership transferThe codebase makes heavy use of OpenZeppelin’s contracts but it has implemented the two-step ownership transfer by itself. OpenZeppelin recently added it with Ownable2Step.sol
- use it instead
ClosePledge
event in retrievePledgeRewards
retrievePledgeRewards
will close a Pledge if it hasn’t been closed yet, but it does not emit the ClosePledge
event - add it
retrievePledgeRewards
Docs for retrievePledgeRewards
say the method retrieves reward from a closed pledge but actually it retrieves them from an expired pledge ONLY, and if it is not closed it closes it. Update docs with the actual action of the method
pledgePercent
does not actually use the percent
argument as a percentage value but as bps value (it divides by 10 000)The pledgePercent()
method gives the impression with its NatSpec and naming that the percent
parameter is a percentage value - from 1 to 100. But it is actually used as a bps value because it is divided by 10000. This can result in unexpected behaviour from a UX standpoint, update naming and docs
/** @notice Event emitted when xx */
commentThe comment is copy-pasted 13 times but it does not bring any value to the reader/auditor/dev - remove it
The _chestAddress
parameter is missing in the NatSpec of the constructor - add it
public
to private
for storage fields with explicit getter functionBoth the pledges
and ownerPledges
storage fields are public
which automatically generates a getter for them, but the code also specifies explicit getters with different names for them. Change their visibility to private
so there is no automatically generated getters for them
In _pledge()
the code does uint256 boostDuration **=** endTimestamp **-** **block**.timestamp;
calculation before actually completely valudate the amount
argument. Move that boostDuration
math further below, after all validations are done
Words with typos in WardenPledge.sol
:
protocalFeeRatio
→ protocolFeeRatio
Creates the contract, set the given base parameters
→ Creates the contract, sets the given base parameters
taget
→ target
balacne
→ balance
ot
→ to
feeamount
→ fee amount
reards
→ rewards
minmum
→ minimum
Platfrom
→ Platform
Address tof the EC2O token
→ Address of the ERC20 token
#0 - c4-judge
2022-11-12T00:13:24Z
kirk-baird marked the issue as grade-a