-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dockerize anvil; forge scripts for deploying seaport, valorem, mock c…
…ontracts (#50) * add anvil script * update gitignore * ignore anvil files * chore: forge init * forge install: forge-std v1.5.3 * forge install: seaport * forge install: seaport-order-validator v0.1.1 * forge install: valorem-core v1.0.0 * drop init foundry files * add forge scripts for seaport and valorem init * add remappings file * drop foundry boilerplate * update readme w anvil info + addresses * drop seaport init script; add script for initializing valorem options * bugfixes for init scripts * add mock erc20 mint, approval, options write * forge install: solmate * preapprove seaport for spending valorem 1155s * refac; init order struct * create and validate seaport order * fix gitmodules merge * feedback: drop usdc, weth, uni; use mocks * drop solmate * feedback: drop unnecessary cast * feedback: udpate readme
- Loading branch information
1 parent
3761aed
commit 3618de2
Showing
11 changed files
with
284 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
/target | ||
.idea | ||
.env | ||
.vscode | ||
|
||
broadcast/ | ||
cache/ | ||
out/ | ||
|
||
# Local settings file - if stored under the repository | ||
settings.toml | ||
settings.toml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,15 @@ | ||
[submodule "proto"] | ||
path = proto | ||
url = [email protected]:valorem-labs-inc/exchange-proto.git | ||
[submodule "lib/forge-std"] | ||
path = lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std | ||
[submodule "lib/seaport"] | ||
path = lib/seaport | ||
url = https://github.com/ProjectOpenSea/seaport | ||
[submodule "lib/seaport-order-validator"] | ||
path = lib/seaport-order-validator | ||
url = https://github.com/ProjectOpenSea/seaport-order-validator | ||
[submodule "lib/valorem-core"] | ||
path = lib/valorem-core | ||
url = https://github.com/valorem-labs-inc/valorem-core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[profile.default] | ||
src = "src" | ||
out = "out" | ||
libs = ["lib"] | ||
|
||
# See more config options https://github.com/foundry-rs/foundry/tree/master/config |
Submodule seaport-order-validator
added at
6a56b4
Submodule valorem-core
added at
0252a9
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ds-test/=lib/forge-std/lib/ds-test/src/ | ||
forge-std/=lib/forge-std/src/ | ||
seaport/=lib/seaport/ | ||
seaport-validator/=lib/seaport-order-validator/ | ||
valorem-core/=lib/valorem-core/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.13; | ||
|
||
import "forge-std/Script.sol"; | ||
import {IERC20} from "forge-std/interfaces/IERC20.sol"; | ||
import { ConsiderationInterface } from "seaport/contracts/interfaces/ConsiderationInterface.sol"; | ||
import "seaport/contracts/lib/ConsiderationStructs.sol"; | ||
|
||
import { ValoremOptionsClearinghouse } from "valorem-core/src/ValoremOptionsClearinghouse.sol"; | ||
import { MockERC20 } from "valorem-core/test/utils/MockERC20.sol"; | ||
|
||
contract InitValoremClearinghouseOptionsScript is Script { | ||
address public constant SEAPORT_A = 0x00000000006c3852cbEf3e08E8dF289169EdE581; | ||
address public constant SEAPORT_VALIDATOR_A = 0xF75194740067D6E4000000003b350688DD770000; | ||
address public constant CLEARINGHOUSE_A = 0x7513F78472606625A9B505912e3C80762f6C9Efb; | ||
|
||
MockERC20 public MOCK_VOL_1; | ||
MockERC20 public MOCK_STABLE; | ||
MockERC20 public MOCK_VOL_2; | ||
|
||
// TODO extract this and pk to .env var | ||
// address corresponding to anvil dev account | ||
// NOTE: this is also expected to be the sender of each transaction in this script, | ||
// and --from should be supplied to the forge script invocation | ||
address payable public constant ORDERER_A = payable(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); | ||
uint256 public constant ORDERER_PK = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; | ||
|
||
uint256 public WETH_USDC_1M_ID; | ||
uint256 public UNI_USDC_1M_ID; | ||
|
||
ConsiderationInterface seaport; | ||
ValoremOptionsClearinghouse clearinghouse; | ||
|
||
function run() public { | ||
vm.startBroadcast(); | ||
|
||
// verify two orders for valorem options | ||
seaport = ConsiderationInterface(SEAPORT_A); | ||
clearinghouse = ValoremOptionsClearinghouse(CLEARINGHOUSE_A); | ||
|
||
mint_and_approve(); | ||
init_option_types(); | ||
|
||
uint256 weth_usdc_claim = clearinghouse.write(WETH_USDC_1M_ID, 10); | ||
uint256 uni_usdc_claim = clearinghouse.write(UNI_USDC_1M_ID, 10); | ||
|
||
vm.stopBroadcast(); | ||
} | ||
|
||
function init_option_types() internal { | ||
uint40 ts = uint40(block.timestamp); | ||
|
||
// create options types | ||
WETH_USDC_1M_ID = clearinghouse.newOptionType({ | ||
underlyingAsset: address(MOCK_VOL_1), | ||
underlyingAmount: 1 ether, | ||
exerciseAsset: address(MOCK_STABLE), | ||
exerciseAmount: 1600 ether, | ||
exerciseTimestamp: ts + 1 days, | ||
expiryTimestamp: ts + 30 days | ||
}); | ||
|
||
UNI_USDC_1M_ID = clearinghouse.newOptionType({ | ||
underlyingAsset: address(MOCK_VOL_2), | ||
underlyingAmount: 1 ether, | ||
exerciseAsset: address(MOCK_STABLE), | ||
exerciseAmount: 2500 ether, | ||
exerciseTimestamp: ts + 1 days, | ||
expiryTimestamp: ts + 30 days | ||
}); | ||
} | ||
|
||
function mint_and_approve() internal { | ||
MOCK_VOL_1 = new MockERC20("Wrapped Ether", "WETH", 18); | ||
MOCK_VOL_2 = new MockERC20("Uniswap", "UNI", 18); | ||
MOCK_STABLE = new MockERC20("USD Coin", "USDC", 6); | ||
|
||
MOCK_VOL_1.mint(ORDERER_A, 1000000 ether); | ||
MOCK_VOL_2.mint(ORDERER_A, 1000000 ether); | ||
MOCK_STABLE.mint(ORDERER_A, 1000000 ether); | ||
|
||
MOCK_VOL_1.approve(CLEARINGHOUSE_A, 1000000 ether); | ||
MOCK_VOL_2.approve(CLEARINGHOUSE_A, 1000000 ether); | ||
MOCK_STABLE.approve(CLEARINGHOUSE_A, 1000000 ether); | ||
|
||
// preapprove seaport to transfer the NFTs | ||
clearinghouse.setApprovalForAll(SEAPORT_A, true); | ||
} | ||
|
||
function init_order() internal{ | ||
uint40 ts = uint40(block.timestamp); | ||
OfferItem[] memory offer = new OfferItem[](1); | ||
offer[0] = OfferItem({ | ||
itemType: ItemType.ERC1155, | ||
token: address(CLEARINGHOUSE_A), | ||
identifierOrCriteria: WETH_USDC_1M_ID, | ||
startAmount: 1, | ||
endAmount: 1 | ||
}); | ||
ConsiderationItem[] memory consideration = new ConsiderationItem[](1); | ||
consideration[0] = ConsiderationItem({ | ||
itemType: ItemType.ERC20, | ||
token: address(MOCK_STABLE), | ||
identifierOrCriteria: WETH_USDC_1M_ID, | ||
startAmount: 1, | ||
endAmount: 1, | ||
recipient: ORDERER_A | ||
}); | ||
// offer 10 WETH/USDC 1M options | ||
// from https://docs.opensea.io/reference/create-an-order | ||
OrderParameters memory weth_usdc_order_params = OrderParameters({ | ||
offerer: ORDERER_A, | ||
zone: address(0x0), // 0x004C00500000aD104D7DBd00e3ae0A5C00560C00 | ||
offer: offer, | ||
consideration: consideration, | ||
orderType: OrderType.FULL_OPEN, | ||
startTime: ts + 1, | ||
endTime: ts + 30 days, | ||
zoneHash: 0x0000000000000000000000000000000000000000000000000000000000000000, | ||
salt: 0, | ||
conduitKey: 0, // 0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000, | ||
totalOriginalConsiderationItems: consideration.length | ||
}); | ||
// needed to calculate signature for the order | ||
OrderComponents memory weth_usdc_order_components = OrderComponents({ | ||
offerer: ORDERER_A, | ||
zone: address(0x0), // 0x004C00500000aD104D7DBd00e3ae0A5C00560C00 | ||
offer: offer, | ||
consideration: consideration, | ||
orderType: OrderType.FULL_OPEN, | ||
startTime: ts + 1, | ||
endTime: ts + 30 days, | ||
zoneHash: 0x0000000000000000000000000000000000000000000000000000000000000000, | ||
salt: 0, | ||
conduitKey: 0, // 0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000, | ||
counter: seaport.getCounter(ORDERER_A) | ||
}); | ||
bytes memory signature = signOrder( | ||
seaport, | ||
ORDERER_PK, | ||
seaport.getOrderHash(weth_usdc_order_components) | ||
); | ||
|
||
// Validates and registers the signature of the order on seaport | ||
Order memory order = Order(weth_usdc_order_params, signature); | ||
Order[] memory orders = new Order[](1); | ||
orders[0] = order; | ||
if(!seaport.validate(orders)){ | ||
revert("invalid order"); | ||
} | ||
} | ||
|
||
function signOrder( | ||
ConsiderationInterface _consideration, | ||
uint256 _pkOfSigner, | ||
bytes32 _orderHash | ||
) internal view returns (bytes memory) { | ||
(bytes32 r, bytes32 s, uint8 v) = getSignatureComponents( | ||
_consideration, | ||
_pkOfSigner, | ||
_orderHash | ||
); | ||
return abi.encodePacked(r, s, v); | ||
} | ||
|
||
function signOrder2098( | ||
ConsiderationInterface _consideration, | ||
uint256 _pkOfSigner, | ||
bytes32 _orderHash | ||
) internal view returns (bytes memory) { | ||
(bytes32 r, bytes32 s, uint8 v) = getSignatureComponents( | ||
_consideration, | ||
_pkOfSigner, | ||
_orderHash | ||
); | ||
uint256 yParity; | ||
if (v == 27) { | ||
yParity = 0; | ||
} else { | ||
yParity = 1; | ||
} | ||
uint256 yParityAndS = (yParity << 255) | uint256(s); | ||
return abi.encodePacked(r, yParityAndS); | ||
} | ||
|
||
function getSignatureComponents( | ||
ConsiderationInterface _consideration, | ||
uint256 _pkOfSigner, | ||
bytes32 _orderHash | ||
) internal view returns (bytes32, bytes32, uint8) { | ||
(, bytes32 domainSeparator, ) = _consideration.information(); | ||
(uint8 v, bytes32 r, bytes32 s) = vm.sign( | ||
_pkOfSigner, | ||
keccak256( | ||
abi.encodePacked(bytes2(0x1901), domainSeparator, _orderHash) | ||
) | ||
); | ||
return (r, s, v); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/usr/bin/env bash | ||
set -x | ||
set -eo pipefail | ||
|
||
# if a docker anvil is running, print instructions to kill it and exit | ||
RUNNING_CONTAINER=$(docker ps --filter 'name=anvil' --format '{{.ID}}') | ||
if [[ -n $RUNNING_CONTAINER ]]; then | ||
echo >&2 "there is a anvil container already running, kill it with" | ||
echo >&2 " docker kill ${RUNNING_CONTAINER}" | ||
exit 1 | ||
fi | ||
|
||
if [[ -z $FORK_RPC_URL ]]; then | ||
echo >&2 "the fork URL for anvil must be defined in the environment variable FORK_RPC_URL" | ||
exit 1 | ||
fi | ||
|
||
echo >&2 "Running anvil with fork URL: $FORK_RPC_URL" | ||
|
||
# Launch Anvil using Docker | ||
docker run \ | ||
-p "8545:8545" \ | ||
-e ANVIL_IP_ADDR=0.0.0.0 \ | ||
--name "anvil_$(date '+%s')" \ | ||
-d ghcr.io/foundry-rs/foundry:latest \ | ||
"anvil -f ${FORK_RPC_URL}" | ||
|
||
until cast age; do | ||
>&2 echo "anvil is still unavailable - sleeping" | ||
sleep 1 | ||
done | ||
|
||
>&2 echo "Anvil is ready to go!" | ||
|
||
forge script scripts/forge/InitValoremClearinghouseOptions.s.sol --broadcast --fork-url http://localhost:8545/ --private-key ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --use 0.8.16 | ||
>&2 echo "Seaport and Valorem Clearinghouse are ready to go!" |