deterministic addr & test bugfixes

This commit is contained in:
Tim Olson
2023-10-08 01:11:33 -04:00
parent 52069cfe0b
commit 1fabd95940
9 changed files with 30 additions and 16 deletions

View File

@@ -2,7 +2,7 @@
# this script requires the jq command $(sudo apt install jq) # this script requires the jq command $(sudo apt install jq)
# first-pass build # first-pass build
forge build forge build "$@"
# calculate the Vault init code hash using the bytecode generated for Vault # calculate the Vault init code hash using the bytecode generated for Vault
# shellcheck disable=SC2046 # shellcheck disable=SC2046
@@ -16,4 +16,4 @@ mkdir gen &> /dev/null
echo "export const VAULT_INIT_CODE_HASH='$VAULT_INIT_CODE_HASH';" > gen/vaultHash.js echo "export const VAULT_INIT_CODE_HASH='$VAULT_INIT_CODE_HASH';" > gen/vaultHash.js
# final build after hash values are set # final build after hash values are set
forge build forge build "$@"

View File

@@ -5,7 +5,7 @@
#db-migrate up #db-migrate up
#cd ../contract #cd ../contract
./bin/build.sh #source ./bin/build.sh
anvil -f arbitrum_ankr --chain-id 1338 & anvil -f arbitrum_ankr --chain-id 1338 &
# todo check anvil result # todo check anvil result
ANVIL_PID=$! ANVIL_PID=$!
@@ -14,7 +14,7 @@ sleep 2
forge script script/Deploy.sol -vvvv --fork-url http://localhost:8545 --broadcast forge script script/Deploy.sol -vvvv --fork-url http://localhost:8545 --broadcast
trap_ctrlc() { trap_ctrlc() {
echo echo exiting anvil
kill $ANVIL_PID kill $ANVIL_PID
} }

3
bin/test.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
./bin/build.sh
forge test -vvvv --fork-url arbitrum_ankr

View File

@@ -4,20 +4,22 @@ pragma abicoder v2;
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol"; import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import "./UniswapSwapper.sol"; import "./UniswapSwapper.sol";
import "forge-std/console2.sol";
library OrderLib { library OrderLib {
// todo safe math and/or bounds checking
uint64 internal constant NO_CHAIN = type(uint64).max; uint64 internal constant NO_CHAIN = type(uint64).max;
uint64 internal constant NO_OCO = type(uint64).max; uint64 internal constant NO_OCO = type(uint64).max;
event DexorderPlaced (uint64 startOrderIndex, uint8 numOrders); event DexorderSwapPlaced (uint64 startOrderIndex, uint8 numOrders);
event DexorderSwapFilled (uint64 orderIndex, uint8 trancheIndex, uint256 amountIn, uint256 amountOut); event DexorderSwapFilled (uint64 orderIndex, uint8 trancheIndex, uint256 amountIn, uint256 amountOut);
event DexorderCompleted (uint64 orderIndex); // todo remove? event DexorderSwapCompleted (uint64 orderIndex); // todo remove?
event DexorderError (uint64 orderIndex, string reason); event DexorderSwapError (uint64 orderIndex, string reason);
// todo If a tranche fails to fill, an order can stay Open forever without any active tranches. maybe replace state with a simple canceled flag // todo If a tranche fails to fill, an order can stay Open forever without any active tranches. maybe replace state with a simple canceled flag
enum SwapOrderState { enum SwapOrderState {
@@ -127,7 +129,6 @@ library OrderLib {
OcoGroup[] ocoGroups; // each indexed OCO group is an array of orderIndexes of orders in the oco group. OcoGroup[] ocoGroups; // each indexed OCO group is an array of orderIndexes of orders in the oco group.
} }
function _placeOrder(OrdersInfo storage self, SwapOrder memory order) internal { function _placeOrder(OrdersInfo storage self, SwapOrder memory order) internal {
SwapOrder[] memory orders = new SwapOrder[](1); SwapOrder[] memory orders = new SwapOrder[](1);
orders[0] = order; orders[0] = order;
@@ -175,7 +176,7 @@ library OrderLib {
status.start = uint32(block.timestamp); status.start = uint32(block.timestamp);
status.ocoGroup = ocoGroup; status.ocoGroup = ocoGroup;
} }
emit DexorderPlaced(startIndex,uint8(orders.length)); emit DexorderSwapPlaced(startIndex,uint8(orders.length));
} }
@@ -279,7 +280,7 @@ library OrderLib {
uint256 remaining = status.order.amount - (status.order.amountIsInput ? status.filledIn : status.filledOut); uint256 remaining = status.order.amount - (status.order.amountIsInput ? status.filledIn : status.filledOut);
if( remaining == 0 ) { // todo dust leeway? if( remaining == 0 ) { // todo dust leeway?
status.state = SwapOrderState.Filled; status.state = SwapOrderState.Filled;
emit DexorderCompleted(orderIndex); emit DexorderSwapCompleted(orderIndex);
if( status.ocoGroup != NO_OCO ) if( status.ocoGroup != NO_OCO )
_cancelOco(self, status.ocoGroup); _cancelOco(self, status.ocoGroup);
} }
@@ -298,7 +299,7 @@ library OrderLib {
SwapOrderState state = self.orders[orderIndex].state; SwapOrderState state = self.orders[orderIndex].state;
if( state == SwapOrderState.Open || state == SwapOrderState.Template ) { if( state == SwapOrderState.Open || state == SwapOrderState.Template ) {
self.orders[orderIndex].state = SwapOrderState.Canceled; self.orders[orderIndex].state = SwapOrderState.Canceled;
emit DexorderCompleted(orderIndex); emit DexorderSwapCompleted(orderIndex);
} }
} }
} }

View File

@@ -60,6 +60,10 @@ contract Vault {
orderList._placeOrders(orders, ocoMode); orderList._placeOrders(orders, ocoMode);
} }
function swapOrderStatus(uint64 orderIndex) public view returns (OrderLib.SwapOrderStatus memory status) {
return orderList.orders[orderIndex];
}
function execute(uint64 orderIndex, uint8 tranche_index, OrderLib.PriceProof memory proof) public function execute(uint64 orderIndex, uint8 tranche_index, OrderLib.PriceProof memory proof) public
returns (string memory error) returns (string memory error)
{ {

View File

@@ -3,13 +3,14 @@ pragma solidity =0.7.6;
pragma abicoder v2; pragma abicoder v2;
import "./Constants.sol"; import "./Constants.sol";
import "forge-std/console2.sol";
library VaultAddress { library VaultAddress {
// keccak-256 hash of the Vault's bytecode (not the deployed bytecode but the initialization bytecode) // keccak-256 hash of the Vault's bytecode (not the deployed bytecode but the initialization bytecode)
// can paste into: // can paste into:
// https://emn178.github.io/online-tools/keccak_256.html // https://emn178.github.io/online-tools/keccak_256.html
bytes32 internal constant VAULT_INIT_CODE_HASH = 0xdc7f6d1305b2c9951dc98f6a745290e4f2b92bf65d346db11dd284dcfcd67aef; bytes32 internal constant VAULT_INIT_CODE_HASH = 0x40d5f4d1aa2f505a4b156599c452d0e7df5003430246ca5798a932dc031a9127;
// the contract being constructed must not have any constructor arguments or the determinism will be broken. instead, use a callback to // the contract being constructed must not have any constructor arguments or the determinism will be broken. instead, use a callback to
// get construction arguments // get construction arguments
@@ -20,13 +21,14 @@ library VaultAddress {
} }
function computeAddress(address factory, address owner, uint8 num) internal pure returns (address vault) { function computeAddress(address factory, address owner, uint8 num) internal pure returns (address vault) {
bytes32 salt = keccak256(abi.encodePacked(owner,num));
vault = address( vault = address(
uint256( uint256(
keccak256( keccak256(
abi.encodePacked( abi.encodePacked(
hex'ff', hex'ff',
factory, factory,
keccak256(abi.encode(owner,num)), salt,
VAULT_INIT_CODE_HASH VAULT_INIT_CODE_HASH
) )
) )

View File

@@ -32,7 +32,7 @@ contract VaultDeployer {
function _deployVault(address owner, uint8 num) internal returns (address payable vault) { function _deployVault(address owner, uint8 num) internal returns (address payable vault) {
parameters = Parameters(owner); parameters = Parameters(owner);
vault = address(new Vault{salt: keccak256(abi.encode(owner,num))}()); vault = address(new Vault{salt: keccak256(abi.encodePacked(owner,num))}());
delete parameters; delete parameters;
emit VaultCreated( owner, num ); emit VaultCreated( owner, num );
} }

View File

@@ -12,6 +12,7 @@ contract TestOrder is MockEnv, Test {
// vault gets 100,000 COIN and 100,000 USD // vault gets 100,000 COIN and 100,000 USD
function setUp() public { function setUp() public {
init();
factory = new Factory(); factory = new Factory();
vault = Vault(factory.deployVault(address(this))); vault = Vault(factory.deployVault(address(this)));
uint256 coinAmount = 100_000 * 10 ** COIN.decimals(); uint256 coinAmount = 100_000 * 10 ** COIN.decimals();
@@ -25,5 +26,4 @@ contract TestOrder is MockEnv, Test {
} }
} }

View File

@@ -7,14 +7,18 @@ import "../src/VaultAddress.sol";
import "forge-std/Test.sol"; import "forge-std/Test.sol";
pragma abicoder v2; pragma abicoder v2;
contract TestVault is Test{ contract TestVault is Test {
Factory public factory; Factory public factory;
Vault public vault; Vault public vault;
function setUp() public { function setUp() public {
factory = new Factory(); factory = new Factory();
console2.log('factory');
console2.log(address(factory));
vault = Vault(factory.deployVault(address(this))); vault = Vault(factory.deployVault(address(this)));
console2.log('vault');
console2.log(address(vault));
} }
function testDeterministicAddress() public { function testDeterministicAddress() public {