Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/test_fixtures/abis/RaindexV6.json

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions src/concrete/raindex/RaindexV6.sol
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,17 @@ contract RaindexV6 is IRaindexV6, IMetaV1_2, ReentrancyGuard, Multicall, Raindex
ClearStateChangeV2 memory clearStateChange =
calculateClearStateChange(aliceOrderIOCalculation, bobOrderIOCalculation);

Float aliceBounty = clearStateChange.aliceOutput.sub(clearStateChange.bobInput);
Float bobBounty = clearStateChange.bobOutput.sub(clearStateChange.aliceInput);

// A negative bounty means there is a spread between the orders. This is a
// critical error because it means the DEX could be exploited if allowed.
// Checked before any vault settlement so a spread always reverts with this
// explicit error.
if (aliceBounty.lt(LibDecimalFloat.FLOAT_ZERO) || bobBounty.lt(LibDecimalFloat.FLOAT_ZERO)) {
revert NegativeBounty();
}

// Pull both orders' outputs into the orderbook before pushing either
// order's input out. Alice's input token is Bob's output token and vice
// versa, so both pulls must precede both pushes for the orderbook to hold
Expand All @@ -737,16 +748,6 @@ contract RaindexV6 is IRaindexV6, IMetaV1_2, ReentrancyGuard, Multicall, Raindex
pushVaultZeroInput(bobOrderIOCalculation);

{
Float aliceBounty = clearStateChange.aliceOutput.sub(clearStateChange.bobInput);
Float bobBounty = clearStateChange.bobOutput.sub(clearStateChange.aliceInput);

// A negative bounty means there is a spread between the orders.
// This is a critical error because it means the DEX could be
// exploited if allowed.
if (aliceBounty.lt(LibDecimalFloat.FLOAT_ZERO) || bobBounty.lt(LibDecimalFloat.FLOAT_ZERO)) {
revert NegativeBounty();
}

increaseVaultBalance(
msg.sender,
aliceOrder.validOutputs[clearConfig.aliceOutputIOIndex].token,
Expand Down
6 changes: 3 additions & 3 deletions src/generated/GenericPoolRaindexV6ArbOrderTaker.pointers.sol

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/generated/GenericPoolRaindexV6FlashBorrower.pointers.sol

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/generated/RaindexV6.pointers.sol

Large diffs are not rendered by default.

Large diffs are not rendered by default.

67 changes: 63 additions & 4 deletions src/lib/deploy/LibRaindexDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ library LibRaindexDeploy {
bytes32 constant RAINDEX_DEPLOYED_CODEHASH_0_1_11 =
0xb9aa0944893a2aa695250428cee0d2e839f3794aebbc229e2070f064598c4b31;

/// The deployed address of the `RaindexV6` contract at the published `0.1.12`
/// tag. (Changed in 0.1.12 — clear3 NegativeBounty guard hoisted ahead of any
/// vault settlement.)
address constant RAINDEX_DEPLOYED_ADDRESS_0_1_12 = 0x37FC0EFec37D19f8A221aa4F8F7600C9ba2AcD20;

/// The runtime code hash of the `RaindexV6` contract at the published `0.1.12`
/// tag.
bytes32 constant RAINDEX_DEPLOYED_CODEHASH_0_1_12 =
0x6dccd7018126439bb9bceec4cd37f5bcfdd5319979fbf70f9faf41450da10b6f;

/// The address of the `RaindexV6SubParser` contract when deployed with
/// the rain standard zoltu deployer.
address constant SUB_PARSER_DEPLOYED_ADDRESS = SUB_PARSER_ADDR;
Expand Down Expand Up @@ -249,6 +259,15 @@ library LibRaindexDeploy {
bytes32 constant SUB_PARSER_DEPLOYED_CODEHASH_0_1_11 =
0x704aadc1ed56f63ff918ab219e6681a5d2851d774e2ee136bbe7904ea3b2fdcd;

/// The deployed address of the `RaindexV6SubParser` contract at the published
/// `0.1.12` tag. (Unchanged since 0.1.11.)
address constant SUB_PARSER_DEPLOYED_ADDRESS_0_1_12 = 0x09Bc7AF266012F44fb41D8Bd682da931666605e1;

/// The runtime code hash of the `RaindexV6SubParser` contract at the
/// published `0.1.12` tag.
bytes32 constant SUB_PARSER_DEPLOYED_CODEHASH_0_1_12 =
0x704aadc1ed56f63ff918ab219e6681a5d2851d774e2ee136bbe7904ea3b2fdcd;

/// The address of the `RouteProcessor4` contract when deployed with the
/// rain standard zoltu deployer.
address constant ROUTE_PROCESSOR_DEPLOYED_ADDRESS = ROUTE_PROCESSOR_ADDR;
Expand Down Expand Up @@ -356,6 +375,15 @@ library LibRaindexDeploy {
bytes32 constant ROUTE_PROCESSOR_DEPLOYED_CODEHASH_0_1_11 =
0xeb3745a79c6ba48e8767b9c355b8e7b79f9d6edeca004e4bb91be4de515a7eeb;

/// The deployed address of the `RouteProcessor4` contract at the published
/// `0.1.12` tag. (Unchanged since 0.1.11.)
address constant ROUTE_PROCESSOR_DEPLOYED_ADDRESS_0_1_12 = 0x6E2d0e71d900474b262E545Bc4C98b71ab368d21;

/// The runtime code hash of the `RouteProcessor4` contract at the published
/// `0.1.12` tag.
bytes32 constant ROUTE_PROCESSOR_DEPLOYED_CODEHASH_0_1_12 =
0xeb3745a79c6ba48e8767b9c355b8e7b79f9d6edeca004e4bb91be4de515a7eeb;

/// The address of the `GenericPoolRaindexV6ArbOrderTaker` contract when
/// deployed with the rain standard zoltu deployer.
address constant GENERIC_POOL_ARB_ORDER_TAKER_DEPLOYED_ADDRESS = GENERIC_POOL_ARB_OT_ADDR;
Expand Down Expand Up @@ -468,6 +496,16 @@ library LibRaindexDeploy {
bytes32 constant GENERIC_POOL_ARB_ORDER_TAKER_DEPLOYED_CODEHASH_0_1_11 =
0x04b0da6d34aaa9b7df623ea46c7849a9e13bcff32dbb02e781b94acaab02bacf;

/// The deployed address of the `GenericPoolRaindexV6ArbOrderTaker` contract
/// at the published `0.1.12` tag. (Changed in 0.1.12 — embeds the redeployed
/// RaindexV6.)
address constant GENERIC_POOL_ARB_ORDER_TAKER_DEPLOYED_ADDRESS_0_1_12 = 0xE84c106B0A89A164d2D65205B9EBAE37c15Fd84a;

/// The runtime code hash of the `GenericPoolRaindexV6ArbOrderTaker` contract
/// at the published `0.1.12` tag.
bytes32 constant GENERIC_POOL_ARB_ORDER_TAKER_DEPLOYED_CODEHASH_0_1_12 =
0x02b17ab238a36ebcedee19fa5a374d6122865be8fff61bf45ad15822c8482030;

/// The address of the `RouteProcessorRaindexV6ArbOrderTaker` contract
/// when deployed with the rain standard zoltu deployer.
address constant ROUTE_PROCESSOR_ARB_ORDER_TAKER_DEPLOYED_ADDRESS = RP_ARB_OT_ADDR;
Expand Down Expand Up @@ -591,6 +629,17 @@ library LibRaindexDeploy {
bytes32 constant ROUTE_PROCESSOR_ARB_ORDER_TAKER_DEPLOYED_CODEHASH_0_1_11 =
0x14f012211cd8e3e0f07777b5e93f1f441a80bbeb8845b762913d7b9362ba71f6;

/// The deployed address of the `RouteProcessorRaindexV6ArbOrderTaker`
/// contract at the published `0.1.12` tag. (Changed in 0.1.12 — embeds the
/// redeployed RaindexV6.)
address constant ROUTE_PROCESSOR_ARB_ORDER_TAKER_DEPLOYED_ADDRESS_0_1_12 =
0x1350420cbf3E9eb8F1734bbe466e0F303579eE24;

/// The runtime code hash of the `RouteProcessorRaindexV6ArbOrderTaker`
/// contract at the published `0.1.12` tag.
bytes32 constant ROUTE_PROCESSOR_ARB_ORDER_TAKER_DEPLOYED_CODEHASH_0_1_12 =
0x9a0d64fd312dc16761f28a7e13e48a8e8ad2f0ba5995c16710514e7524f43ee2;

/// The address of the `GenericPoolRaindexV6FlashBorrower` contract when
/// deployed with the rain standard zoltu deployer.
address constant GENERIC_POOL_FLASH_BORROWER_DEPLOYED_ADDRESS = GENERIC_POOL_FB_ADDR;
Expand Down Expand Up @@ -703,8 +752,18 @@ library LibRaindexDeploy {
bytes32 constant GENERIC_POOL_FLASH_BORROWER_DEPLOYED_CODEHASH_0_1_11 =
0x09617589f55317f6e41e1a1fba10d0d77996af310e5ce4d2705249fcaf3cb029;

uint256 constant RAINDEX_START_BLOCK_ARBITRUM = 473877912;
uint256 constant RAINDEX_START_BLOCK_BASE = 47384882;
uint256 constant RAINDEX_START_BLOCK_FLARE = 63007250;
uint256 constant RAINDEX_START_BLOCK_POLYGON = 88569424;
/// The deployed address of the `GenericPoolRaindexV6FlashBorrower` contract
/// at the published `0.1.12` tag. (Changed in 0.1.12 — embeds the redeployed
/// RaindexV6.)
address constant GENERIC_POOL_FLASH_BORROWER_DEPLOYED_ADDRESS_0_1_12 = 0x032d9D94A79909F3b337ECFE6f73f4e86bA79c7E;

/// The runtime code hash of the `GenericPoolRaindexV6FlashBorrower` contract
/// at the published `0.1.12` tag.
bytes32 constant GENERIC_POOL_FLASH_BORROWER_DEPLOYED_CODEHASH_0_1_12 =
0x03cde49152f7b5e29826ea8c561481b747b86be1f5cb4136fa064be6e4ac1c0d;

uint256 constant RAINDEX_START_BLOCK_ARBITRUM = 473899359;
uint256 constant RAINDEX_START_BLOCK_BASE = 47387582;
uint256 constant RAINDEX_START_BLOCK_FLARE = 63011168;
uint256 constant RAINDEX_START_BLOCK_POLYGON = 88573024;
}
16 changes: 8 additions & 8 deletions subgraph/networks.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"arbitrum-one": {
"Raindex": {
"address": "0x1115EBC9C82F074454F6AC28f123B0684A453aF7",
"startBlock": 473877912
"address": "0x37FC0EFec37D19f8A221aa4F8F7600C9ba2AcD20",
"startBlock": 473899359
}
},
"matic": {
"Raindex": {
"address": "0x1115EBC9C82F074454F6AC28f123B0684A453aF7",
"startBlock": 88569424
"address": "0x37FC0EFec37D19f8A221aa4F8F7600C9ba2AcD20",
"startBlock": 88573024
}
},
"base": {
"Raindex": {
"address": "0x1115EBC9C82F074454F6AC28f123B0684A453aF7",
"startBlock": 47384882
"address": "0x37FC0EFec37D19f8A221aa4F8F7600C9ba2AcD20",
"startBlock": 47387582
}
},
"flare": {
"Raindex": {
"address": "0x1115EBC9C82F074454F6AC28f123B0684A453aF7",
"startBlock": 63007250
"address": "0x37FC0EFec37D19f8A221aa4F8F7600C9ba2AcD20",
"startBlock": 63011168
}
}
}
2 changes: 1 addition & 1 deletion subgraph/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dataSources:
name: Raindex
network: sepolia
source:
address: "0x1115EBC9C82F074454F6AC28f123B0684A453aF7"
address: "0x37FC0EFec37D19f8A221aa4F8F7600C9ba2AcD20"
abi: Raindex
startBlock: 0
mapping:
Expand Down
40 changes: 40 additions & 0 deletions test/concrete/raindex/RaindexV6.takeOrder.vaultZeroInput.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
TaskV2
} from "raindex-interface-0.1.1/src/interface/IRaindexV6.sol";
import {Float, LibDecimalFloat} from "rain-math-float-0.1.1/src/lib/LibDecimalFloat.sol";
import {NegativeBounty} from "../../../src/concrete/raindex/RaindexV6.sol";

/// @title RaindexV6TakeOrderVaultZeroInputTest
/// @notice An order with a `vaultId == 0` INPUT is settled as a direct wallet
Expand Down Expand Up @@ -673,4 +674,43 @@ contract RaindexV6TakeOrderVaultZeroInputTest is RaindexV6ExternalRealTest {
vm.expectRevert();
iRaindex.vaultBalance2(owner, address(token0), bytes32(0));
}

/// A `clear3` whose orders cross into a negative bounty reverts with the
/// explicit `NegativeBounty` before any vault is settled. Both orders take
/// and give via vault 0 against an orderbook with zero ambient balance, so
/// the only funds that could settle a vault-0 input are the capped outputs
/// pulled from the counterparty. The negative-bounty guard runs ahead of that
/// settlement, so the explicit error is the revert rather than the vault-0
/// token push running short first.
///
/// Alice: gives token0, wants token1 @ IO ratio 2 (both vault 0)
/// Bob: gives token1, wants token0 @ IO ratio 2 (both vault 0)
///
/// Each order's input demand (1 * 2 = 2) caps to the counterparty's max
/// output (1): each output is 0.5 and each input is 1, so both bounties are
/// 0.5 - 1 = -0.5.
function testClearNegativeBountyVaultZeroRevertsNegativeBounty() external {
token0.mint(alice, 10e18);
vm.prank(alice);
token0.approve(address(iRaindex), 10e18);

token1.mint(bob, 10e18);
vm.prank(bob);
token1.approve(address(iRaindex), 10e18);

OrderV4 memory aliceOrder = LibTestTakeOrder.addOrderWithExpression(
vm, alice, "_ _: 1 2;:;", address(token1), bytes32(0), address(token0), bytes32(0)
);
OrderV4 memory bobOrder = LibTestTakeOrder.addOrderWithExpression(
vm, bob, "_ _: 1 2;:;", address(token0), bytes32(0), address(token1), bytes32(0)
);

assertEq(token0.balanceOf(address(iRaindex)), 0, "orderbook starts with zero ambient token0");
assertEq(token1.balanceOf(address(iRaindex)), 0, "orderbook starts with zero ambient token1");

vm.expectRevert(NegativeBounty.selector);
iRaindex.clear3(
aliceOrder, bobOrder, ClearConfigV2(0, 0, 0, 0, 0, 0), new SignedContextV1[](0), new SignedContextV1[](0)
);
}
}
Loading