Platform: Code4rena
Start Date: 15/12/2022
Pot Size: $128,000 USDC
Total HM: 28
Participants: 111
Period: 19 days
Judge: GalloDaSballo
Total Solo HM: 1
Id: 194
League: ETH
Rank: 59/111
Findings: 1
Award: $122.82
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0xSmartContract, AkshaySrivastav, HollaDieWaldfee, RaymondFam, Rolezn, ast3ros, betweenETHlines, brgltd, chaduke, codeislight, cozzetti, lukris02, pauliax, sces60107
122.8177 USDC - $122.82
contract Ocyticus is Base { ... constructor(Storage storageAddress) Base(storageAddress) { // assign 1 to 'version' variable defenders[msg.sender] = true; }
File: ProtocolDAO.sol 156: function setExpectedAVAXRewardsRate(uint256 rate) public onlyMultisig valueNotGreaterThanOne(rate) { 157: setUint(keccak256("ProtocolDAO.ExpectedAVAXRewardsRate"), rate);
File: ProtocolDAO.sol 190: function registerContract(address addr, string memory name) public onlyGuardian { 198: function unregisterContract(address addr) public onlyGuardian { File: Base.sol 10: constructor(Storage _gogoStorageAddress) { File: Oracle.sol 28: function setOneInch(address addr) external onlyGuardian {
File: MinipoolManager.sol function resetMinipoolData(int256 index) private { deleteBytes32(keccak256(abi.encodePacked("minipool.item", index, ".txID"))); deleteUint(keccak256(abi.encodePacked("minipool.item", index, ".startTime"))); deleteUint(keccak256(abi.encodePacked("minipool.item", index, ".endTime"))); deleteUint(keccak256(abi.encodePacked("minipool.item", index, ".avaxTotalRewardAmt"))); deleteUint(keccak256(abi.encodePacked("minipool.item", index, ".avaxNodeOpRewardAmt"))); deleteUint(keccak256(abi.encodePacked("minipool.item", index, ".avaxLiquidStakerRewardAmt"))); deleteUint(keccak256(abi.encodePacked("minipool.item", index, ".ggpSlashAmt"))); deleteBytes32(keccak256(abi.encodePacked("minipool.item", index, ".errorCode"))); }
avaxAssignmentRequest
the extra parameter would be sufficient and better UX.File: MiniPoolManager.sol 196: function createMinipool( 197: address nodeID, 198: uint256 duration, 199: uint256 delegationFee, 200: uint256 avaxAssignmentRequest 201: ) external payable whenNotPaused {
entering high values would lead to higher expected rewards in getExpectedAVAXRewardsAmt that could damage the slashing process, and also in the RialtoSimulator despite being out of scope, with the current implementation, it could lead to the rewards being amplified when called by processMinipoolEndWithRewards().
it should have values max up to 1 ether <=> 10%, due to the latter, it could lead the node operators to set the fees at 100% and profit off of it all.
#0 - GalloDaSballo
2023-01-24T13:10:28Z
1 - Ocyticus constructor, the inherited Base contract, lacks assigning 'version' variable L
2 - remember to remove ProtocolDAO.setExpectedAVAXRewardsRate() function in production. L
3 - check contract addresses inputs are contracts by checking code size is greater than zero. L, equivalent to address(0) check
4 - use delete instead of set function in MiniPoolManager.resetMiniPoolData() to save on gas fees and improve on readability. Doesnt' save gas, disagree
5 - in MiniPoolManager.createMinipool() has payable and avaxAssignmentRequest parameters, which are both must be equal, therefore using only msg.value as a value instead of passing avaxAssignmentRequest the extra parameter would be sufficient and better UX. Disputing https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L207-L212
if ( // Current rule is matched funds must be 1:1 nodeOp:LiqStaker msg.value != avaxAssignmentRequest || avaxAssignmentRequest > dao.getMinipoolMaxAVAXAssignment() || avaxAssignmentRequest < dao.getMinipoolMinAVAXAssignment() ) {
6 - creating a new MiniPool lacks checking duration validity L due to poor description
7 - creating a new MiniPool lacks checking delegationFee L
#1 - GalloDaSballo
2023-02-03T17:13:03Z
5L
#2 - c4-judge
2023-02-03T22:09:42Z
GalloDaSballo marked the issue as grade-b