Skip to content

Commit

Permalink
test full order flow (#40)
Browse files Browse the repository at this point in the history
* updated to arb for consideration token

* add nfv 1,15

* 15 and 137

* added order-126

* add orders and update env loading contracts

* Update readme

* readme cleanup

* stored extra data during listing.

* Update example env

* packag.json fixes

---------

Co-authored-by: Patrick Gallagher <[email protected]>
  • Loading branch information
MrDeadCe11 and pi0neerpat authored Jun 18, 2024
1 parent 760b523 commit 6a5592c
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 120 deletions.
40 changes: 17 additions & 23 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
ARB_MAINNET_RPC=
ARB_MAINNET_PK=
# NETWORK: Arbitrum-sepolia
ARB_SEPOLIA_RPC=
ARB_SEPOLIA_OFFERER_PK=
ARB_SEPOLIA_BUYER_PK=
# put the public address of your defaultKey here if you're using the cast wallet
SIP15_ZONE_SEPOLIA_ADDRESS=0xcafc335d2f5bd0e929b4edbf526eb74fa4c49924
VAULT721_SEPOLIA_ADDRESS=0x05AC7e3ac152012B980407dEff2655c209667E4c
VAULT721_SEPOLIA_ADAPTER_ADDRESS=0xc5736e1F01FB4f013C152B8315019CA20d30FC50
ENCODING_HELPER_SEPOLIA=0x672d358f171ae309dc43fc7b5ff3065e8248efe1

# NETWORK: Arbitrum
ARB_MAINNET_RPC=
ARB_MAINNET_OFFERER_PK=
ARB_MAINNET_BUYER_PK=
SIP15_ZONE_MAINNET_ADDRESS=
VAULT721_MAINNET_ADDRESS=0x0005AFE00fF7E7FF83667bFe4F2996720BAf0B36
VAULT721_ADAPTER_MAINNET_ADDRESS=
ENCODING_HELPER_MAINNET=

# Public address of defaultKey for 'cast'
DEFAULT_KEY_PUBLIC_ADDRESS=

ARB_ETHERSCAN_API_KEY=
OPENSEA_API_KEY=

# run `anvil` and copy a private key from anvil terminal
ANVIL_ONE=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
ANVIL_RPC=http://127.0.0.1:8545

FOUNDRY_PROFILE=debug

VAULT721_SEPOLIA_ADDRESS=0x05AC7e3ac152012B980407dEff2655c209667E4c
VAULT721_MAINNET_ADDRESS=0x0005AFE00fF7E7FF83667bFe4F2996720BAf0B36
VAULT721_ANVIL_ADDRESS=

OPENSEA_API_KEY=

SIP15_ZONE_ANVIL_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3
SIP15_ZONE_SEPOLIA_ADDRESS=0xD658CB9C7626e147c4bd8B8Ef401f1Fb42cA7695
SIP15_ZONE_MAINNET_ADDRESS=

VAULT721_MAINNET_ADAPTER_ADDRESS=
VAULT721_SEPOLIA_ADAPTER_ADDRESS=0xc5736e1F01FB4f013C152B8315019CA20d30FC50
VAULT721_ANVIL_ADAPTER_ADDRESS=0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512

ENCODING_HELPER_MAINNET=
ENCODING_HELPER_ANVIL=
ENCODING_HELPER_SEPOLIA=0x672d358f171ae309dc43fc7b5ff3065e8248efe1
42 changes: 33 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,43 @@
</a>
</p>

Template for projects using `@opendollar/contracts` with Foundry
# Dynamic Traits Enforcement Zone

**Documentation**
A Seaport zone for specifying and enforcing values of ERC-7496 Dynamic Traits

## Documentation
View the SIP-15 standard: https://github.com/open-dollar/SIPs/blob/main/SIPS/sip-15.md

- https://book.getfoundry.sh/
- https://contracts.opendollar.com
- https://docs.opendollar.com
## Setup

1. Copy the `.env.example` and update the following values:

## Attn:
```bash
ARB_SEPOLIA_RPC=

before running these tests, you must cd into the lib/seaport folder and run
ARB_SEPOLIA_OFFERER_PK=
ARB_SEPOLIA_BUYER_PK=
```

`FOUNDRY_PROFILE=optimized forge build`
2. Use the “Offerer” wallet to open a vault on Open Dollar testnet https://app.dev.opendollar.com

2. User the “Buyer” wallet to mint the consideration token "ARB" at https://sepolia.arbiscan.io/address/0x3018EC2AD556f28d2c0665d10b55ebfa469fD749#writeContract


## Create listing

```bash
yarn
yarn build

# Create Listing
yarn create-listing <chainName> <tokenId> <considerationAmountInEther>
yarn create-listing sepolia 313 0.000001

# Execute listing
yarn fulfill <chainName> <orderPath>
yarn fulfill sepolia orders/order-1-1718667016.json
```

Notes:
- Vaults have a 100 second cooldown on testnet before they can be transferred.
- Order `endTime` is 24 hours
34 changes: 34 additions & 0 deletions orders/order-1-1718667016.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"parameters": {
"offerer": "0xC295763Eed507d4A0f8B77241c03dd3354781a15",
"zone": "0xcafc335d2f5bd0e929b4edbf526eb74fa4c49924",
"zoneHash": "0xfd67bb706f1e45b1ac95cb3ba2b364f80af346352b62b4348c1cbf33633b40d0",
"startTime": 1718667016,
"endTime": "1718753416",
"orderType": 2,
"offer": [
{
"itemType": 2,
"token": "0x05AC7e3ac152012B980407dEff2655c209667E4c",
"identifierOrCriteria": "1",
"startAmount": "1",
"endAmount": "1"
}
],
"consideration": [
{
"itemType": 1,
"token": "0x3018EC2AD556f28d2c0665d10b55ebfa469fD749",
"identifierOrCriteria": "0",
"startAmount": "1000000000000000000",
"endAmount": "1000000000000000000",
"recipient": "0xC295763Eed507d4A0f8B77241c03dd3354781a15"
}
],
"totalOriginalConsiderationItems": 1,
"salt": "0x0000000000000000000000000000000000000000000000007c75eaa0d516a5c9",
"conduitKey": "0x0000000000000000000000000000000000000000000000000000000000000000",
"counter": "0"
},
"signature": "0x7efe32dadfad76f5a3e2e6709667fdb1a0d21047c80592d95e3b9f99868de70f995f07dd9f97d7b1831a2a846b76836699fd5108bb665f4463302c86e9b68791"
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
{
"parameters": {
"offerer": "0x941E92c9Eff78a2b7217057752cf938040a59aE9",
"offerer": "0x09D5Bd4a4f1dA1A965fE24EA54bce3d37661E056",
"zone": "0xcafc335d2f5bd0e929b4edbf526eb74fa4c49924",
"zoneHash": "0x7f1aff2effced629bfcae4e0a3f749094b2af49ee70357d6bca4e8a2d36eea57",
"startTime": 1718408958,
"endTime": "1718495358",
"zoneHash": "0x2e84022d4abd1b0d5d91d272d53d7aae7a1f8ccadde7259a2626113abf33b41d",
"startTime": 1718665562,
"endTime": "1718751962",
"orderType": 2,
"offer": [
{
"itemType": 2,
"token": "0x05AC7e3ac152012B980407dEff2655c209667E4c",
"identifierOrCriteria": "128",
"identifierOrCriteria": "126",
"startAmount": "1",
"endAmount": "1"
}
],
"consideration": [
{
"itemType": 1,
"token": "0x8c12A21C8D62d794f78E02aE9e377Abee4750E87",
"token": "0x3018EC2AD556f28d2c0665d10b55ebfa469fD749",
"identifierOrCriteria": "0",
"startAmount": "1000000",
"endAmount": "1000000",
"recipient": "0x941E92c9Eff78a2b7217057752cf938040a59aE9"
"recipient": "0x09D5Bd4a4f1dA1A965fE24EA54bce3d37661E056"
}
],
"totalOriginalConsiderationItems": 1,
"salt": "0x000000000000000000000000000000000000000000000000cb3ba97239090623",
"salt": "0x000000000000000000000000000000000000000000000000a073fa8ee34f684f",
"conduitKey": "0x0000000000000000000000000000000000000000000000000000000000000000",
"counter": "0"
},
"signature": "0xf76030ec389f1f116d3297f58b586092568403b856a56f8696da82d4e088197f858bcc8142a387a3911355bee84751dc009e365484a94e5c7977a16ace75d270"
"signature": "0x485f3071f0393186999aefe80b7466e750a6e12b01ad421da317fffc3a41e2df71828b8cfbfa0a5f9c2ad32ac7cabc17a13b8d9fa054e9a8d9353fdba41ca6f5"
}
13 changes: 8 additions & 5 deletions script/createListing.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { ethers } from "ethers";
import { BytesLike, ethers } from "ethers";
import { Web3Environment } from "./utils/constants";
import { ItemType } from "@opensea/seaport-js/src/constants";
import { CreateOrderInput } from "@opensea/seaport-js/lib/types";
import { convertBigIntsToStrings, getExtraData } from "./utils/helpers";
import {
convertBigIntsToStrings,
getExtraData,
convertOrder,
} from "./utils/helpers";
import fs from "fs";
import path from "path";

Expand All @@ -27,7 +31,7 @@ const createSIP15ZoneListing = async (
/** @TODO Fill in the token address and token ID of the NFT you want to sell, as well as the price */
///////////////////////////////////////////////////////////////////////////////////////////////////////
let considerationTokenAddress: string =
"0x8c12A21C8D62d794f78E02aE9e377Abee4750E87";
"0x3018EC2AD556f28d2c0665d10b55ebfa469fD749";

listingAmount = ethers.parseEther(listingAmount).toString();
const extraData = await getExtraData(web3Env, vaultId.toString());
Expand All @@ -36,7 +40,6 @@ const createSIP15ZoneListing = async (
const zoneHash = ethers.keccak256(extraData);
const timeStamp = (await provider.getBlock("latest"))!.timestamp;
const timeDelay = await vault721.timeDelay();
console.log("ZoneAddress", sip15ZoneAddress);

const createOrderInput: CreateOrderInput = {
offer: [
Expand Down Expand Up @@ -70,7 +73,7 @@ const createSIP15ZoneListing = async (

const order = await executeAllActions();

const parsedOrder = convertBigIntsToStrings(order);
const parsedOrder = convertBigIntsToStrings(convertOrder(order, extraData));

const outPath = path.join(
`orders/order-${order.parameters.offer[0].identifierOrCriteria}-${order.parameters.startTime}.json`
Expand Down
22 changes: 12 additions & 10 deletions script/fulfillSIP15Order.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Web3Environment, ERC20ABI } from "./utils/constants";
import { convertBigIntsToStrings, getExtraData } from "./utils/helpers";
import {
getExtraData,
OrderWithExtraData,
convertOrder,
} from "./utils/helpers";
import { OrderWithCounter } from "@opensea/seaport-js/src/types";
import { ethers } from "ethers";
import fs from "fs";
Expand All @@ -15,19 +19,16 @@ const fulfillSIP15Order = async (chain: string, pathToOrder: string) => {
const wallet = web3Env.wallet;

const _path = path.join(pathToOrder);
const orderWithCounter = JSON.parse(
const orderWithExtraData: OrderWithExtraData = JSON.parse(
fs.readFileSync(_path, "utf-8")
) as OrderWithCounter;
) as OrderWithExtraData;

const erc20 = new ethers.Contract(
orderWithCounter.parameters.consideration[0].token,
orderWithExtraData.order.parameters.consideration[0].token,
ERC20ABI.abi,
wallet
);
const extraData = await getExtraData(
web3Env,
orderWithCounter.parameters.offer[0].identifierOrCriteria
);
const extraData = orderWithExtraData.extraData.toString();

try {
const conduitAddress = (await seaport.contract.information())
Expand All @@ -38,16 +39,17 @@ const fulfillSIP15Order = async (chain: string, pathToOrder: string) => {
await erc20.approve(conduitAddress, ethers.MaxUint256);

const { executeAllActions } = await seaport.fulfillOrder({
order: orderWithCounter,
order: orderWithExtraData.order,
unitsToFill: 1,
extraData: extraData,
exactApproval: true,
});

const fulfillment = await executeAllActions();

console.log("fulfillerAddress: ", wallet.address);
console.log("Successfully fulfilled a listing:", fulfillment.to);
} catch (error) {
console.log("fulfillerAddress: ", wallet.address);
console.error("Error in fulfillment:", error);
}
};
Expand Down
34 changes: 15 additions & 19 deletions script/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,31 +55,27 @@ const mainnetContracts = stringToObject(mainnetContractsString);
export const OPENSEA_API_KEY = process.env.OPENSEA_API_KEY;
export const ARB_SEPOLIA_BUYER_PK = process.env.ARB_SEPOLIA_BUYER_PK;
export const ARB_SEPOLIA_OFFERER_PK = process.env.ARB_SEPOLIA_OFFERER_PK;
export const ARB_MAINNET_PK = process.env.ARB_MAINNET_PK;
export const ARB_MAINNET_BUYER_PK = process.env.ARB_MAINNET_BUYER_PK;
export const ARB_MAINNET_OFFERER_PK = process.env.ARB_MAINNET_OFFERER_PK;
export const ARB_SEPOLIA_RPC = process.env.ARB_SEPOLIA_RPC;
export const ARB_MAINNET_RPC = process.env.ARB_MAINNET_RPC;

// export const SIP15_ZONE_MAINNET_ADDRESS = checkMainnetAddress(mainnetDeployments, 0)
export const SIP15_ZONE_SEPOLIA_ADDRESS = checkSepoliaAddress(
sepoliaDeployments,
0
);
export const SIP15_ZONE_MAINNET_ADDRESS =
process.env.SIP15_ZONE_MAINNET_ADDRESS;
export const SIP15_ZONE_SEPOLIA_ADDRESS =
process.env.SIP15_ZONE_SEPOLIA_ADDRESS;

export const VAULT721_SEPOLIA_ADAPTER_ADDRESS = checkSepoliaAddress(
sepoliaDeployments,
1
);
export const VAULT721_SEPOLIA_ADAPTER_ADDRESS =
process.env.VAULT721_SEPOLIA_ADAPTER_ADDRESS;

// export const VAULT721_MAINNET_ADAPTER_ADDRESS = checkMainnetAddress(mainnetDeployments, 1)
export const VAULT721_ADAPTER_MAINNET_ADDRESS =
process.env.VAULT721_ADAPTER_MAINNET_ADDRESS;
export const VAULT721_SEPOLIA_ADDRESS = sepoliaContracts.Vault721_Address;
export const VAULT721_MAINNET_ADDRESS = mainnetContracts.Vault721_Address;
export const VAULT721_ANVIL_ADDRESS = process.env.VAULT721_ANVIL_ADDRESS;

// export const ENCODING_HELPER_MAINNET = checkMainnetAddress(mainnetDeployments, 2)
export const ENCODING_HELPER_SEPOLIA = checkSepoliaAddress(
sepoliaDeployments,
2
);
export const ENCODING_HELPER_MAINNET = process.env.ENCODING_HELPER_MAINNET;
export const ENCODING_HELPER_SEPOLIA = process.env.ENCODING_HELPER_SEPOLIA;

export const Vault721AdapterABI = require("../../abis/Vault721Adapter.json");
export const EncodeSubstandard5ForEthersABI = require("../../abis/EncodeSubstandard5ForEthers.json");
Expand Down Expand Up @@ -150,11 +146,11 @@ export class Web3Environment {
// throw new Error('.env VARS missing: ARB_MAINNET_RPC, ARB_MAINNET_PK')
// }

// if (VAULT721_MAINNET_ADAPTER_ADDRESS && VAULT721_MAINNET_ADDRESS) {
// vault721AdapterAddress = VAULT721_MAINNET_ADAPTER_ADDRESS;
// if (VAULT721_ADAPTER_MAINNET_ADDRESS && VAULT721_MAINNET_ADDRESS) {
// vault721AdapterAddress = VAULT721_ADAPTER_MAINNET_ADDRESS;
// vault721Address = VAULT721_MAINNET_ADDRESS;
// } else {
// throw new Error("VAULT721_MAINNET_ADAPTER_ADDRESS undefined");
// throw new Error("VAULT721_ADAPTER_MAINNET_ADDRESS undefined");
// }

// // if no helper exists deploy helper
Expand Down
Loading

0 comments on commit 6a5592c

Please sign in to comment.