Skip to content

Commit

Permalink
Merge pull request #85 from flood-protocol/tests-and-documentation
Browse files Browse the repository at this point in the history
small changes
  • Loading branch information
fulminmaxi authored Dec 14, 2023
2 parents e5c3641 + 51b53bc commit 62229ef
Show file tree
Hide file tree
Showing 13 changed files with 20 additions and 287 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/Vectorized/solady
[submodule "lib/leb128-nooffset"]
path = lib/leb128-nooffset
url = https://github.com/Shungy/leb128-nooffset
3 changes: 2 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
remappings = [
"@openzeppelin/=lib/openzeppelin-contracts/contracts/",
"permit2/=lib/permit2/",
"solady/=lib/solady/src/"
"solady/=lib/solady/src/",
"leb128=lib/leb128-nooffset/src/"
]
solc_version = "0.8.23"
evm_version = "paris"
Expand Down
1 change: 1 addition & 0 deletions lib/leb128-nooffset
Submodule leb128-nooffset added at 30bfb0
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flood-contracts",
"version": "1.0.0",
"version": "1.1.0",
"description": "Flood contracts are the smart contracts that power Flood, the optimal routing protocol.",
"homepage": "https://flood.bid",
"bugs": "https://github.com/flood-protocol/flood-contracts/issues",
Expand Down
4 changes: 2 additions & 2 deletions src/EncodedCalls.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity 0.8.23;
import {IEncodedCalls} from "./interfaces/IEncodedCalls.sol";

// Libraries
import {LEB128} from "./libraries/LEB128.sol";
import {LEB128Lib} from "leb128/LEB128Lib.sol";

abstract contract EncodedCalls is IEncodedCalls {
address[] public decoders;
Expand All @@ -23,7 +23,7 @@ abstract contract EncodedCalls is IEncodedCalls {
// ensure such byte exists.

// Get the decoded decoder ID, and the new calldata ptr.
(uint256 decoderId, uint256 ptr) = LEB128.rawDecodeUint({ptr: 1});
(uint256 decoderId, uint256 ptr) = LEB128Lib.rawDecodeUint({ptr: 1});

// Get the decoder.
address decoder = decoders[decoderId];
Expand Down
14 changes: 3 additions & 11 deletions src/FloodPlain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {ReentrancyGuard} from "@openzeppelin/utils/ReentrancyGuard.sol";
import {OrderHash} from "./libraries/OrderHash.sol";
import {Hooks, SELECTOR_EXTENSION} from "./libraries/Hooks.sol";
import {Duplicates} from "./libraries/Duplicates.sol";
import {Address} from "@openzeppelin/utils/Address.sol";
import {SafeERC20} from "@openzeppelin/token/ERC20/utils/SafeERC20.sol";

// Interfaces
Expand All @@ -22,7 +21,6 @@ import {ISignatureTransfer} from "permit2/src/interfaces/ISignatureTransfer.sol"

contract FloodPlain is IFloodPlain, EncodedCalls, OnChainOrders, ReentrancyGuard {
using SafeERC20 for IERC20;
using Address for address payable;
using OrderHash for Order;
using Duplicates for Item[];
using Hooks for Hook[];
Expand Down Expand Up @@ -69,10 +67,8 @@ contract FloodPlain is IFloodPlain, EncodedCalls, OnChainOrders, ReentrancyGuard
_permitTransferOffer(order, package.signature, orderHash, msg.sender);

// Transfer consideration item from msg.sender to offerer.
address token = order.consideration.token;
uint256 amount = order.consideration.amount;
if (token == address(0)) payable(order.recipient).sendValue(amount);
else IERC20(token).safeTransferFrom(msg.sender, order.recipient, amount);
IERC20(order.consideration.token).safeTransferFrom(msg.sender, order.recipient, amount);

// Execute post hooks.
order.postHooks.execute();
Expand Down Expand Up @@ -108,9 +104,7 @@ contract FloodPlain is IFloodPlain, EncodedCalls, OnChainOrders, ReentrancyGuard
if (amount < order.consideration.amount) revert InsufficientAmountReceived();

// Transfer declared consideration amount from the fulfiller to the offerer.
address token = order.consideration.token;
if (token == address(0)) payable(order.recipient).sendValue(amount);
else IERC20(token).safeTransferFrom(fulfiller, order.recipient, amount);
IERC20(order.consideration.token).safeTransferFrom(fulfiller, order.recipient, amount);

// Execute post hooks.
order.postHooks.execute();
Expand Down Expand Up @@ -154,9 +148,7 @@ contract FloodPlain is IFloodPlain, EncodedCalls, OnChainOrders, ReentrancyGuard
if (amount < order.consideration.amount) revert InsufficientAmountReceived();

// Transfer declared consideration amount from the fulfiller to the offerer.
address token = order.consideration.token;
if (token == address(0)) payable(order.recipient).sendValue(amount);
else IERC20(token).safeTransferFrom(fulfiller, order.recipient, amount);
IERC20(order.consideration.token).safeTransferFrom(fulfiller, order.recipient, amount);

// Execute post hooks.
order.postHooks.execute();
Expand Down
1 change: 0 additions & 1 deletion src/Zone.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ contract Zone is IAuthZone, AccessControlDefaultAdminRules, Pausable {
}

function setFee(FeeInfo calldata newFee) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (newFee.bps > 500) revert FeeTooHigh();
_fee.bps = newFee.bps;
_fee.recipient = newFee.recipient;
emit FeeUpdated(newFee);
Expand Down
22 changes: 0 additions & 22 deletions src/libraries/LEB128.sol

This file was deleted.

16 changes: 8 additions & 8 deletions test/EncodedCalls.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import "./utils/FloodPlainTestShared.sol";
import {EncodedCalls} from "src/EncodedCalls.sol";
import {IEncodedCalls} from "src/interfaces/IEncodedCalls.sol";

import {LEB128} from "src/libraries/LEB128.sol";
import {LEB128Encode} from "./utils/LEB128Encode.sol";
import {LEB128Lib} from "leb128/LEB128Lib.sol";

contract EncodedCallsContract is EncodedCalls {
uint256 public val;
Expand All @@ -24,13 +23,13 @@ contract MockDecoder {
assembly {
ptr := data.offset
}
(uint256 a, uint256 newPtr) = LEB128.rawDecodeUint(ptr);
(uint256 a, uint256 newPtr) = LEB128Lib.rawDecodeUint(ptr);
require(data.length >= newPtr - ptr, "DECODING_ERROR");
return abi.encodeWithSelector(EncodedCallsContract.changeVal.selector, a);
}
}

contract EncodedCallsTest is LEB128Encode, FloodPlainTestShared {
contract EncodedCallsTest is FloodPlainTestShared {
EncodedCallsContract encodedCalls;
MockDecoder decoder;

Expand Down Expand Up @@ -66,7 +65,7 @@ contract EncodedCallsTest is LEB128Encode, FloodPlainTestShared {
encodedCalls.addDecoder(address(0x69));
}
uint256 decoderId = encodedCalls.addDecoder(address(decoder));
bytes memory callData = abi.encodePacked(hex"00", _encode(decoderId), _encode(a));
bytes memory callData = abi.encodePacked(hex"00", LEB128Lib.encode(decoderId), LEB128Lib.encode(a));
(bool success, bytes memory data) = address(encodedCalls).call(callData);

assertTrue(success);
Expand All @@ -77,7 +76,8 @@ contract EncodedCallsTest is LEB128Encode, FloodPlainTestShared {

function test_invalidDecoderId() public {
encodedCalls.addDecoder(address(decoder));
bytes memory callData = abi.encodePacked(hex"00", _encode(69), _encode(69));
uint256 val = 69;
bytes memory callData = abi.encodePacked(hex"00", LEB128Lib.encode(val), LEB128Lib.encode(val));
(bool success, bytes memory data) = address(encodedCalls).call(callData);
assertFalse(success);
assertEq(data, abi.encodeWithSignature("Panic(uint256)", 0x32));
Expand All @@ -92,15 +92,15 @@ contract EncodedCallsTest is LEB128Encode, FloodPlainTestShared {

function test_decoderError() public {
uint256 decoderId = encodedCalls.addDecoder(address(decoder));
bytes memory callData = abi.encodePacked(hex"00", _encode(decoderId));
bytes memory callData = abi.encodePacked(hex"00", LEB128Lib.encode(decoderId));
(bool success, bytes memory data) = address(encodedCalls).call(callData);
assertFalse(success);
assertEq(data, abi.encodeWithSignature("Error(string)", "DECODING_ERROR"));
}

function test_methodError() public {
uint256 decoderId = encodedCalls.addDecoder(address(decoder));
bytes memory callData = abi.encodePacked(hex"00", _encode(decoderId));
bytes memory callData = abi.encodePacked(hex"00", LEB128Lib.encode(decoderId));
(bool success, bytes memory data) = address(encodedCalls).call(callData);
assertFalse(success);
assertEq(data, abi.encodeWithSignature("Error(string)", "DECODING_ERROR"));
Expand Down
93 changes: 0 additions & 93 deletions test/FloodPlain.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,6 @@ contract FloodPlainTest is FloodPlainTestShared {
assertEq(token1.balanceOf(address(account3.addr)), 500);
}

function test_fulfillEthOrder() public {
IFloodPlain.SignedOrder memory signedOrder = setup_mostBasicOrder();

signedOrder.order.consideration.token = address(0);
deal(address(fulfiller), 500);

signedOrder.signature = getSignature(signedOrder.order, account0);

// Prechecks.
assertEq(token0.balanceOf(address(account0.addr)), 500);
assertEq(address(account0.addr).balance, 0);
assertEq(token0.balanceOf(address(fulfiller)), 0);
assertEq(address(fulfiller).balance, 500);

// Fill the order.
book.fulfillOrder(signedOrder, address(fulfiller), "");

// Assertions.
assertEq(token0.balanceOf(address(account0.addr)), 0);
assertEq(address(account0.addr).balance, 500);
assertEq(token0.balanceOf(address(fulfiller)), 500);
assertEq(address(fulfiller).balance, 0);
}

function test_fulfillMultiItemOrder() public {
IFloodPlain.SignedOrder memory signedOrder = setup_multiItemOrder();

Expand Down Expand Up @@ -122,19 +98,6 @@ contract FloodPlainTest is FloodPlainTestShared {
book.fulfillOrder(signedOrder, address(maliciousFulfiller), "");
}

function test_RevertWhenInsufficientEthConsiderationReceived() public {
IFloodPlain.SignedOrder memory signedOrder = setup_mostBasicOrder();

signedOrder.order.consideration.token = address(0);
deal(address(maliciousFulfiller), 500);

signedOrder.signature = getSignature(signedOrder.order, account0);

// Filling order fails.
vm.expectRevert(abi.encodeWithSignature("AddressInsufficientBalance(address)", address(book)));
book.fulfillOrder(signedOrder, address(maliciousFulfiller), "");
}

function test_RevertWhenInsufficientConsiderationIndicated() public {
IFloodPlain.SignedOrder memory signedOrder = setup_mostBasicOrder();

Expand Down Expand Up @@ -398,25 +361,6 @@ contract FloodPlainTest is FloodPlainTestShared {
assertEq(token1.balanceOf(address(this)), 0);
}

function test_fulfillDirectEthOrder() public {
IFloodPlain.SignedOrder memory signedOrder = setup_mostBasicOrder();

signedOrder.order.consideration.token = address(0);

signedOrder.signature = getSignature(signedOrder.order, account0);

uint256 balanceBefore = address(this).balance;

// Fill the order.
book.fulfillOrder{value: 500}(signedOrder);

// Assertions.
assertEq(token0.balanceOf(address(account0.addr)), 0);
assertEq(address(account0.addr).balance, 500);
assertEq(token0.balanceOf(address(this)), 500);
assertEq(address(this).balance, balanceBefore - 500);
}

function test_fulfillMultiItemDirectOrder() public {
IFloodPlain.SignedOrder memory signedOrder = setup_multiItemOrder();

Expand Down Expand Up @@ -459,18 +403,6 @@ contract FloodPlainTest is FloodPlainTestShared {
book.fulfillOrder(signedOrder);
}

function test_RevertDirectOrderWhenInsufficientEthConsiderationReceived() public {
IFloodPlain.SignedOrder memory signedOrder = setup_mostBasicOrder();

signedOrder.order.consideration.token = address(0);

signedOrder.signature = getSignature(signedOrder.order, account0);

// Filling order fails.
vm.expectRevert(abi.encodeWithSignature("AddressInsufficientBalance(address)", address(book)));
book.fulfillOrder{value: 499}(signedOrder);
}

function test_revertDirectOrderWhenOfferTokenRepeated(uint256 indexA, uint256 indexB) public {
indexA = bound(indexA, 0, 2);
indexB = bound(indexB, 0, 2);
Expand Down Expand Up @@ -545,31 +477,6 @@ contract FloodPlainTest is FloodPlainTestShared {
assertEq(token1.balanceOf(address(batchFulfiller)), 0);
}

function test_fulfillEthBatchOrder() public {
IFloodPlain.SignedOrder[] memory signedOrders = new IFloodPlain.SignedOrder[](2);
signedOrders[0] = setup_mostBasicOrder();
signedOrders[1] = setup_mostBasicOrder();

signedOrders[1].order.nonce = 1;
signedOrders[1].order.consideration.token = address(0);
signedOrders[1].signature = getSignature(signedOrders[1].order, account0);

// Send tokens to fulfiller to fill the order.
deal(address(token1), address(batchFulfiller), 500);
deal(address(batchFulfiller), 500);

// Fill the order.
book.fulfillOrders(signedOrders, address(batchFulfiller), "");

// Assertions.
assertEq(token0.balanceOf(address(account0.addr)), 0);
assertEq(token1.balanceOf(address(account0.addr)), 500);
assertEq(address(account0.addr).balance, 500);
assertEq(token0.balanceOf(address(batchFulfiller)), 1000);
assertEq(token1.balanceOf(address(batchFulfiller)), 0);
assertEq(address(batchFulfiller).balance, 0);
}

function test_RevertBatchFillWhenDeadlineExpire() public {
IFloodPlain.SignedOrder[] memory signedOrders = new IFloodPlain.SignedOrder[](2);
signedOrders[0] = setup_mostBasicOrder();
Expand Down
Loading

0 comments on commit 62229ef

Please sign in to comment.