Skip to content

Commit 9ecf645

Browse files
authored
Merge pull request #430 from rsksmart/feature/FLY-2215
Fix/FLY-2215
2 parents 887a61c + 296c6f0 commit 9ecf645

File tree

8 files changed

+135
-15
lines changed

8 files changed

+135
-15
lines changed

src/CollateralManagement.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ contract CollateralManagementContract is
113113
uint256 rewardPercentage,
114114
IPauseRegistry pauseRegistry
115115
) external initializer {
116+
if (rewardPercentage > TOTAL_REWARD_PERCENTAGE) {
117+
revert InvalidRewardPercentage(TOTAL_REWARD_PERCENTAGE, rewardPercentage);
118+
}
116119
if (address(pauseRegistry).code.length == 0) revert Flyover.NoContract(address(pauseRegistry));
117120
__AccessControlDefaultAdminRules_init(initialDelay, defaultAdmin);
118121
__ReentrancyGuard_init();
@@ -142,6 +145,9 @@ contract CollateralManagementContract is
142145
/// @param rewardPercentage The new reward percentage
143146
// solhint-disable-next-line comprehensive-interface
144147
function setRewardPercentage(uint256 rewardPercentage) external onlyRole(DEFAULT_ADMIN_ROLE) {
148+
if (rewardPercentage > TOTAL_REWARD_PERCENTAGE) {
149+
revert InvalidRewardPercentage(TOTAL_REWARD_PERCENTAGE, rewardPercentage);
150+
}
145151
emit RewardPercentageSet(_rewardPercentage, rewardPercentage);
146152
_rewardPercentage = rewardPercentage;
147153
}

src/interfaces/ICollateralManagement.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ interface ICollateralManagement is IPausable {
7878
/// @param from The address of the liquidity provider
7979
error NothingToWithdraw(address from);
8080

81+
/// @notice Emitted when reward percentage exceeds the allowed maximum
82+
/// @param maxRewardPercentage The maximum allowed reward percentage (basis points)
83+
/// @param passedRewardPercentage The provided reward percentage (basis points)
84+
error InvalidRewardPercentage(uint256 maxRewardPercentage, uint256 passedRewardPercentage);
85+
8186
/// @notice Adds peg in collateral to an account
8287
/// @param addr The address of the account
8388
/// @dev This function requires the COLLATERAL_ADDER role

src/test-contracts/PegOutPayer.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ contract PegOutPayer {
2727
}
2828

2929
function executePegOut(QuotesV2.PegOutQuote calldata quote, bytes calldata signature) external {
30-
uint256 total = quote.value + quote.gasFee + quote.callFee + quote.productFeeAmount;
30+
uint256 total = quote.value + quote.gasFee + quote.callFee;
3131
if (address(this).balance < total) {
3232
revert InsufficientBalance(address(this).balance, total);
3333
}

test/collateral/Configuration.t.sol

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pragma solidity 0.8.25;
33

44
import {CollateralTestBase} from "./CollateralTestBase.sol";
55
import {CollateralManagementContract} from "../../src/CollateralManagement.sol";
6+
import {ICollateralManagement} from "../../src/interfaces/ICollateralManagement.sol";
67
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
78
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
89
import {Flyover} from "../../src/libraries/Flyover.sol";
@@ -105,7 +106,67 @@ contract ConfigurationTest is CollateralTestBase {
105106
TEST_DEFAULT_ADMIN_DELAY,
106107
TEST_MIN_COLLATERAL,
107108
TEST_RESIGN_DELAY_BLOCKS,
108-
TEST_REWARD_PERCENTAGE
109+
TEST_REWARD_PERCENTAGE,
110+
pauseRegistry
111+
);
112+
}
113+
114+
function test_Initialize_RevertsWhenRewardPercentageExceedsMaximum()
115+
public
116+
{
117+
uint256 invalidRewardPercentage = collateralManagement
118+
.TOTAL_REWARD_PERCENTAGE() + 1;
119+
CollateralManagementContract implementation = new CollateralManagementContract();
120+
bytes memory initData = abi.encodeCall(
121+
CollateralManagementContract.initialize,
122+
(
123+
owner,
124+
TEST_DEFAULT_ADMIN_DELAY,
125+
TEST_MIN_COLLATERAL,
126+
TEST_RESIGN_DELAY_BLOCKS,
127+
invalidRewardPercentage,
128+
pauseRegistry
129+
)
130+
);
131+
132+
vm.expectRevert(
133+
abi.encodeWithSelector(
134+
ICollateralManagement.InvalidRewardPercentage.selector,
135+
collateralManagement.TOTAL_REWARD_PERCENTAGE(),
136+
invalidRewardPercentage
137+
)
138+
);
139+
new ERC1967Proxy(address(implementation), initData);
140+
}
141+
142+
function test_Initialize_AllowsMaximumBoundary() public {
143+
uint256 maxRewardPercentage = collateralManagement
144+
.TOTAL_REWARD_PERCENTAGE();
145+
CollateralManagementContract implementation = new CollateralManagementContract();
146+
bytes memory initData = abi.encodeCall(
147+
CollateralManagementContract.initialize,
148+
(
149+
owner,
150+
TEST_DEFAULT_ADMIN_DELAY,
151+
TEST_MIN_COLLATERAL,
152+
TEST_RESIGN_DELAY_BLOCKS,
153+
maxRewardPercentage,
154+
pauseRegistry
155+
)
156+
);
157+
158+
ERC1967Proxy proxy = new ERC1967Proxy(
159+
address(implementation),
160+
initData
161+
);
162+
CollateralManagementContract collateralManagementWithMaxReward = CollateralManagementContract(
163+
payable(address(proxy))
164+
);
165+
166+
assertEq(
167+
collateralManagementWithMaxReward.getRewardPercentage(),
168+
maxRewardPercentage,
169+
"Initialize should accept maximum basis points value"
109170
);
110171
}
111172

@@ -145,6 +206,51 @@ contract ConfigurationTest is CollateralTestBase {
145206
);
146207
}
147208

209+
function test_SetRewardPercentage_RevertsWhenExceedingMaximum() public {
210+
uint256 initialRewardPercentage = collateralManagement
211+
.getRewardPercentage();
212+
uint256 invalidRewardPercentage = collateralManagement
213+
.TOTAL_REWARD_PERCENTAGE() + 1;
214+
215+
vm.startPrank(owner);
216+
vm.expectRevert(
217+
abi.encodeWithSelector(
218+
ICollateralManagement.InvalidRewardPercentage.selector,
219+
collateralManagement.TOTAL_REWARD_PERCENTAGE(),
220+
invalidRewardPercentage
221+
)
222+
);
223+
collateralManagement.setRewardPercentage(invalidRewardPercentage);
224+
vm.stopPrank();
225+
226+
assertEq(
227+
collateralManagement.getRewardPercentage(),
228+
initialRewardPercentage,
229+
"RewardPercentage should remain unchanged after revert"
230+
);
231+
}
232+
233+
function test_SetRewardPercentage_AllowsMaximumBoundary() public {
234+
uint256 oldRewardPercentage = collateralManagement
235+
.getRewardPercentage();
236+
uint256 maxRewardPercentage = collateralManagement
237+
.TOTAL_REWARD_PERCENTAGE();
238+
239+
vm.prank(owner);
240+
vm.expectEmit(true, true, false, false);
241+
emit CollateralManagementContract.RewardPercentageSet(
242+
oldRewardPercentage,
243+
maxRewardPercentage
244+
);
245+
collateralManagement.setRewardPercentage(maxRewardPercentage);
246+
247+
assertEq(
248+
collateralManagement.getRewardPercentage(),
249+
maxRewardPercentage,
250+
"RewardPercentage should accept maximum basis points value"
251+
);
252+
}
253+
148254
// ============ setResignDelayInBlocks function tests ============
149255

150256
function test_SetResignDelayInBlocks_OnlyAllowsOwnerToModify() public {

test/discovery/Registration.t.sol

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ contract RegistrationTest is DiscoveryTestBase {
1818
FlyoverDiscovery implementation = new FlyoverDiscovery();
1919

2020
vm.expectRevert(abi.encodeWithSignature("InvalidInitialization()"));
21-
implementation.initialize(owner, 0, address(collateralManagement));
21+
implementation.initialize(
22+
owner,
23+
0,
24+
address(collateralManagement),
25+
pauseRegistry
26+
);
2227
}
2328

2429
function test_Register_RegistersProvidersAndIncrementsLastProviderId()

test/pegin/Configuration.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ contract ConfigurationTest is PegInTestBase {
9191
TEST_DUST_THRESHOLD,
9292
TEST_MIN_PEGIN,
9393
address(collateralManagement),
94-
false
94+
false,
95+
pauseRegistry
9596
);
9697
}
9798

test/pegout/Configuration.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ contract ConfigurationTest is PegOutTestBase {
6767
TEST_DUST_THRESHOLD,
6868
address(collateralManagement),
6969
false,
70-
TEST_BTC_BLOCK_TIME
70+
TEST_BTC_BLOCK_TIME,
71+
pauseRegistry
7172
);
7273
}
7374

test/pegout/Withdraw.t.sol

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ contract WithdrawTest is PegOutTestBase {
6464
);
6565

6666
bytes32 quoteHash = pegOutContract.hashPegOutQuote(quote);
67-
bytes memory signature = signQuote(fullLp, quoteHash);
67+
bytes memory signature = signQuote(fullLp, quote);
6868
changeReceiver.setFail(true);
6969

7070
vm.prank(user);
@@ -238,7 +238,7 @@ contract WithdrawTest is PegOutTestBase {
238238
);
239239

240240
bytes32 quoteHash = pegOutContract.hashPegOutQuote(quote);
241-
bytes memory signature = signQuote(fullLp, quoteHash);
241+
bytes memory signature = signQuote(fullLp, quote);
242242
receiver.setFail(true);
243243

244244
vm.prank(user);
@@ -268,6 +268,7 @@ contract WithdrawTest is PegOutTestBase {
268268
callFee: 100000000000000,
269269
penaltyFee: 10000000000000,
270270
value: value,
271+
chainId: block.chainid,
271272
gasFee: 100,
272273
lbcAddress: address(pegOutContract),
273274
lpRskAddress: lp,
@@ -307,7 +308,7 @@ contract WithdrawTest is PegOutTestBase {
307308

308309
function signQuote(
309310
address signer,
310-
bytes32 quoteHash
311+
Quotes.PegOutQuote memory quote
311312
) internal view returns (bytes memory) {
312313
uint256 privateKey;
313314
if (signer == fullLp) {
@@ -320,13 +321,8 @@ contract WithdrawTest is PegOutTestBase {
320321
revert("Unknown signer");
321322
}
322323

323-
bytes32 ethSignedMessageHash = keccak256(
324-
abi.encodePacked("\x19Ethereum Signed Message:\n32", quoteHash)
325-
);
326-
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
327-
privateKey,
328-
ethSignedMessageHash
329-
);
324+
bytes32 eip712Hash = pegOutContract.hashPegOutQuoteEIP712(quote);
325+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, eip712Hash);
330326
return abi.encodePacked(r, s, v);
331327
}
332328
}

0 commit comments

Comments
 (0)