Skip to content

Commit ae02ea5

Browse files
Merge pull request #2916 from rainlanguage/fix-2909-take-orders-length-word
Zero the length word of takeOrders4's orderIOCalculationsToHandle
2 parents 96e291f + 56731d1 commit ae02ea5

8 files changed

Lines changed: 125 additions & 20 deletions

File tree

‎crates/test_fixtures/abis/RaindexV6.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎src/concrete/raindex/RaindexV6.sol‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ contract RaindexV6 is IRaindexV6, IMetaV1_2, ReentrancyGuard, Multicall, Raindex
385385
assembly ("memory-safe") {
386386
let ptr := mload(0x40)
387387
orderIOCalculationsToHandle := ptr
388+
mstore(ptr, 0)
388389
mstore(0x40, add(ptr, mul(add(length, 1), 0x20)))
389390
}
390391
}

‎src/generated/candidate/GenericPoolRaindexV6ArbOrderTaker.sol‎

Lines changed: 5 additions & 5 deletions
Large diffs are not rendered by default.

‎src/generated/candidate/GenericPoolRaindexV6FlashBorrower.sol‎

Lines changed: 5 additions & 5 deletions
Large diffs are not rendered by default.

‎src/generated/candidate/RaindexV6.sol‎

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

‎src/generated/candidate/RouteProcessorRaindexV6ArbOrderTaker.sol‎

Lines changed: 5 additions & 5 deletions
Large diffs are not rendered by default.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: LicenseRef-DCL-1.0
2+
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
3+
pragma solidity =0.8.25;
4+
5+
import {RaindexV6ExternalRealTest} from "test/util/abstract/RaindexV6ExternalRealTest.sol";
6+
import {LibRaindexDeploy} from "src/lib/deploy/LibRaindexDeploy.sol";
7+
import {LibTestTakeOrder} from "test/util/lib/LibTestTakeOrder.sol";
8+
import {MockToken} from "test/util/concrete/MockToken.sol";
9+
import {
10+
OrderV4,
11+
TakeOrderConfigV4,
12+
TakeOrdersConfigV5,
13+
SignedContextV1,
14+
TaskV2
15+
} from "raindex-interface-0.1.8/src/interface/IRaindexV6.sol";
16+
import {Float, LibDecimalFloat} from "rain-math-float-0.3.10/src/lib/LibDecimalFloat.sol";
17+
18+
/// @title RaindexV6TakeOrderDirtyFreeMemoryTest
19+
/// @notice `takeOrders4` settles exactly the taken orders when the memory past
20+
/// the free memory pointer is nonzero on entry.
21+
contract RaindexV6TakeOrderDirtyFreeMemoryTest is RaindexV6ExternalRealTest {
22+
using LibDecimalFloat for Float;
23+
24+
address internal owner = address(uint160(uint256(keccak256("owner.rain.test"))));
25+
address internal bob = address(uint160(uint256(keccak256("bob.rain.test"))));
26+
27+
bytes32 internal constant OUTPUT_VAULT_ID = bytes32(uint256(0x01));
28+
29+
MockToken internal token0;
30+
MockToken internal token1;
31+
32+
constructor() {
33+
vm.etch(
34+
LibRaindexDeploy.RAINDEX_DEPLOYED_ADDRESS,
35+
vm.getDeployedCode("RaindexV6DirtyFreeMemoryHarness.sol:RaindexV6DirtyFreeMemoryHarness")
36+
);
37+
}
38+
39+
function setUp() public {
40+
token0 = new MockToken("Token Zero", "TK0", 18);
41+
token1 = new MockToken("Token One", "TK1", 18);
42+
}
43+
44+
function _deposit(address who, MockToken token, bytes32 vaultId, uint256 amount) internal {
45+
token.mint(who, amount * 1e18);
46+
vm.startPrank(who);
47+
token.approve(address(iRaindex), amount * 1e18);
48+
// forge-lint: disable-next-line(unsafe-typecast)
49+
iRaindex.deposit4(address(token), vaultId, LibDecimalFloat.packLossless(int256(amount), 0), new TaskV2[](0));
50+
vm.stopPrank();
51+
}
52+
53+
function testTakeOrdersDirtyFreeMemorySettlesOnlyTakenOrders() external {
54+
_deposit(owner, token1, OUTPUT_VAULT_ID, 10);
55+
OrderV4 memory taken = LibTestTakeOrder.addOrderWithExpression(
56+
vm, owner, "_ _:3 1;:;", address(token0), bytes32(0), address(token1), OUTPUT_VAULT_ID
57+
);
58+
OrderV4 memory zeroAmount = LibTestTakeOrder.addOrderWithExpression(
59+
vm, owner, "_ _:0 1;:;", address(token0), bytes32(0), address(token1), OUTPUT_VAULT_ID
60+
);
61+
62+
token0.mint(bob, 3e18);
63+
vm.prank(bob);
64+
token0.approve(address(iRaindex), 3e18);
65+
66+
TakeOrderConfigV4[] memory orders = new TakeOrderConfigV4[](2);
67+
orders[0] = TakeOrderConfigV4(taken, 0, 0, new SignedContextV1[](0));
68+
orders[1] = TakeOrderConfigV4(zeroAmount, 0, 0, new SignedContextV1[](0));
69+
TakeOrdersConfigV5 memory config = LibTestTakeOrder.defaultTakeConfig(orders);
70+
config.maximumIO = LibDecimalFloat.packLossless(10, 0);
71+
72+
vm.prank(bob);
73+
(Float totalTakerInput, Float totalTakerOutput) = iRaindex.takeOrders4(config);
74+
75+
assertTrue(totalTakerInput.eq(LibDecimalFloat.packLossless(3, 0)), "taker input");
76+
assertTrue(totalTakerOutput.eq(LibDecimalFloat.packLossless(3, 0)), "taker output");
77+
assertEq(token0.balanceOf(owner), 3e18, "owner wallet");
78+
assertEq(token0.balanceOf(bob), 0, "taker token0");
79+
assertEq(token1.balanceOf(bob), 3e18, "taker token1");
80+
assertEq(token0.balanceOf(address(iRaindex)), 0, "orderbook token0");
81+
}
82+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: LicenseRef-DCL-1.0
2+
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
3+
pragma solidity =0.8.25;
4+
5+
import {RaindexV6} from "src/concrete/raindex/RaindexV6.sol";
6+
7+
/// @dev RaindexV6 whose `nonReentrant` entry fills the memory past the free
8+
/// memory pointer with nonzero words, so allocations inside guarded functions
9+
/// cannot rely on that memory being zero.
10+
contract RaindexV6DirtyFreeMemoryHarness is RaindexV6 {
11+
uint256 internal constant DIRTY_WORDS = 0x100;
12+
uint256 internal constant DIRTY_WORD = 1;
13+
14+
function _reentrancyGuardStorageSlot() internal pure override returns (bytes32) {
15+
assembly ("memory-safe") {
16+
let start := mload(0x40)
17+
let end := add(start, mul(DIRTY_WORDS, 0x20))
18+
for { let cursor := start } lt(cursor, end) { cursor := add(cursor, 0x20) } { mstore(cursor, DIRTY_WORD) }
19+
}
20+
return super._reentrancyGuardStorageSlot();
21+
}
22+
}

0 commit comments

Comments
 (0)