Platform: Code4rena
Start Date: 07/08/2023
Pot Size: $36,500 USDC
Total HM: 11
Participants: 125
Period: 3 days
Judge: alcueca
Total Solo HM: 4
Id: 274
League: ETH
Rank: 19/125
Findings: 2
Award: $233.51
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: deadrxsezzz
Also found by: 0xComfyCat, Brenzee, Team_Rocket, Yanchuan, auditsea, bin2chen, cducrest, markus_ether, oakcobalt
211.9105 USDC - $211.91
Adding a new gauge
without setting the default time_weight[gauge]
may cause subsequent points_weight[gauge][t]
to be 0
in GaugeController.add_gauge()
, Just set isValidGauge[gauge]
to true, and didn't modify time_weight[gauge]
time_weight[gauge]
always defaults to 0
function add_gauge(address _gauge) external onlyGovernance { require(!isValidGauge[_gauge], "Gauge already exists"); @> isValidGauge[_gauge] = true; emit NewGauge(_gauge); }
When time_weight[gauge]
is 0, it will cause subsequent epoch
s to not be calculated properly
function _get_weight(address _gauge_addr) private returns (uint256) { uint256 t = time_weight[_gauge_addr]; @> if (t > 0) { Point memory pt = points_weight[_gauge_addr][t]; for (uint256 i; i < 500; ++i) { if (t > block.timestamp) break; t += WEEK; uint256 d_bias = pt.slope * WEEK; if (pt.bias > d_bias) { pt.bias -= d_bias; uint256 d_slope = changes_weight[_gauge_addr][t]; pt.slope -= d_slope; } else { pt.bias = 0; pt.slope = 0; } @> points_weight[_gauge_addr][t] = pt; if (t > block.timestamp) time_weight[_gauge_addr] = t; } return pt.bias; } else { return 0; } }
Here is the test case.
After the second week weight
becomes 0
add to GaugeController.t.sol
function testNewGuage() public { vm.startPrank(gov); gc.add_gauge(gauge1); vm.stopPrank(); vm.deal(user1, 1010 ether); uint256 lockStart = block.timestamp; vm.prank(user1); ve.createLock{value: 1000 ether}(1000 ether); vm.startPrank(user1); gc.vote_for_gauge_weights(gauge1, 10000); assertEq(gc.vote_user_power(user1), 10000); vm.stopPrank(); skip(WEEK); //1 week laster gc.checkpoint_gauge(gauge1); uint256 _rel_weigth_next = gc.gauge_relative_weight(gauge1, block.timestamp); console.log("next week weight:",_rel_weigth_next); skip(WEEK); //2 week laster utils.mineBlocks(1); gc.checkpoint_gauge(gauge1); uint256 _rel_weigth_two_week = gc.gauge_relative_weight(gauge1, block.timestamp); console.log("two week weight:",_rel_weigth_two_week); }
$ forge test --match-test testNewGuage -vvv Running 1 test for src/test/GaugeController.t.sol:GaugeControllerTest [PASS] testNewGuage() (gas: 756546) Logs: next week weight: 1000000000000000000 two week weight: 0
init time_weight[gauge]
function add_gauge(address _gauge) external onlyGovernance { require(!isValidGauge[_gauge], "Gauge already exists"); isValidGauge[_gauge] = true; + _change_gauge_weight(_gauge, 0); emit NewGauge(_gauge); }
Context
#0 - c4-pre-sort
2023-08-12T10:01:31Z
141345 marked the issue as low quality report
#1 - c4-pre-sort
2023-08-12T10:01:40Z
141345 marked the issue as remove high or low quality report
#2 - c4-pre-sort
2023-08-12T14:45:11Z
141345 marked the issue as primary issue
#3 - c4-pre-sort
2023-08-12T14:52:07Z
141345 marked the issue as duplicate of #288
#4 - c4-judge
2023-08-25T10:27:07Z
alcueca marked the issue as duplicate of #401
#5 - c4-judge
2023-08-25T10:28:06Z
alcueca marked the issue as duplicate of #288
#6 - c4-judge
2023-08-25T10:36:19Z
alcueca marked the issue as satisfactory
#7 - c4-judge
2023-08-25T22:44:44Z
alcueca changed the severity to 2 (Med Risk)
#8 - c4-judge
2023-08-25T22:45:02Z
alcueca changed the severity to 3 (High Risk)
🌟 Selected for report: ltyu
Also found by: 0xDING99YA, 3docSec, KmanOfficial, MrPotatoMagic, RED-LOTUS-REACH, Tendency, Yuki, bart1e, bin2chen, carrotsmuggler, cducrest, kaden, mert_eren, pep7siup, popular00, qpzm, seerether, zhaojie
21.6049 USDC - $21.60
withdraw()
if a delegatee set up, it cannot withdraw after the expiration
Currently withdraw()
requires the delegatee to be yourself
function withdraw() external nonReentrant { LockedBalance memory locked_ = locked[msg.sender]; // Validate inputs require(locked_.amount > 0, "No lock"); @> require(locked_.end <= block.timestamp, "Lock not expired"); @> require(locked_.delegatee == msg.sender, "Lock delegated"); ...
So if you have a delegatee set up, you need to change it to yourself first
but setting it to yourself restricts toLocked
can't be expired.
function delegate(address _addr) external nonReentrant { ... require(toLocked.amount > 0, "Delegatee has no lock"); @> require(toLocked.end > block.timestamp, "Delegatee lock expired"); require(toLocked.end >= fromLocked.end, "Only delegate to longer lock"); _delegate(delegatee, fromLocked, value, LockAction.UNDELEGATE); _delegate(_addr, toLocked, value, LockAction.DELEGATE); }
Trying to increase the expiration time via increaseAmount()
doesn't work either, again with limitations.
// @dev A lock is active until both lock.amount==0 and lock.end<=block.timestamp function increaseAmount(uint256 _value) external payable nonReentrant { LockedBalance memory locked_ = locked[msg.sender]; // Validate inputs require(_value > 0, "Only non zero amount"); require(msg.value == _value, "Invalid value"); require(locked_.amount > 0, "No lock"); @> require(locked_.end > block.timestamp, "Lock expired"); ...
This leads to the fact that if the user has a delegatee and it expires, it cannot be withdraw. It's locked in the contract.
Add mechanism to grow lock time
Context
#0 - c4-pre-sort
2023-08-13T15:52:47Z
141345 marked the issue as duplicate of #112
#1 - c4-judge
2023-08-24T07:16:02Z
alcueca marked the issue as duplicate of #82
#2 - c4-judge
2023-08-24T07:20:40Z
alcueca changed the severity to 2 (Med Risk)
#3 - c4-judge
2023-08-24T07:38:35Z
alcueca marked the issue as partial-50
#4 - c4-pre-sort
2023-08-24T08:20:04Z
141345 marked the issue as not a duplicate
#5 - c4-pre-sort
2023-08-24T08:20:24Z
141345 marked the issue as not a duplicate
#6 - c4-pre-sort
2023-08-24T08:22:26Z
141345 marked the issue as duplicate of #211
#7 - c4-judge
2023-08-24T21:16:33Z
alcueca marked the issue as partial-50
#8 - c4-judge
2023-08-26T21:24:29Z
alcueca changed the severity to 3 (High Risk)