Skip to content

Commit

Permalink
an ENS name used for a contract target must be correctly configured
Browse files Browse the repository at this point in the history
  • Loading branch information
MrDeadCe11 committed Jun 11, 2024
1 parent 5e9a804 commit 09ce5d1
Show file tree
Hide file tree
Showing 10 changed files with 564 additions and 110 deletions.
26 changes: 18 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
ARB_MAINNET_RPC=
ARB_MAINNET_PK=

ARB_SEPOLIA_RPC=
ARB_SEPOLIA_PK=
ARB_ETHERSCAN_API_KEY=
DEFAULT_KEY_PUBLIC_ADDRESS=
# put the public address of your defaultKey here if you're using the cast wallet
DEFAULT_KEY_PUBLIC_ADDRESS=

ARB_ETHERSCAN_API_KEY=P6DZ75FA2M4WPHNXTIBGKJX4STQP8CGU4G

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

VAULT721_SEPOLIA_ADDRESS=0x05AC7e3ac152012B980407dEff2655c209667E4c
FOUNDRY_PROFILE=debug

VAULT712_SEPOLIA_ADDRESS=0x05AC7e3ac152012B980407dEff2655c209667E4c
VAULT712_MAINNET_ADDRESS=0x0005AFE00fF7E7FF83667bFe4F2996720BAf0B36
VAULT721_ANVIL_ADDRESS=

OPENSEA_API_KEY=
WALLET_PRIV_KEY=
OPENSEA_API_KEY=092134c8da1a42eaaf6cc48c0d1c9fc2

SIP15_ZONE_SEPOLIA_ADDRESS=
SIP15_ZONE_ANVIL_ADDRESS=
SIP15_ZONE_SEPOLIA_ADDRESS=0xD658CB9C7626e147c4bd8B8Ef401f1Fb42cA7695
SIP15_ZONE_MAINNET_ADDRESS=

VAULT712_MAINNET_ADAPATER_ADDRESS=
VAULT721_SEPOLIA_ADAPATER_ADDRESS=
VAULT721_SEPOLIA_ADAPATER_ADDRESS=0xc5736e1F01FB4f013C152B8315019CA20d30FC50
VAULT721_ANVIL_ADAPATER_ADDRESS=

ENCODING_HELPER=
ENCODING_HELPER_ANVIL=
35 changes: 29 additions & 6 deletions script/DeploySIP15Zone.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ contract DeploySIP15ZoneWithENV is Script {
console2.log('deployer balance:', deployer.balance);
}

function _deploy() internal {
new SIP15Zone();
}
}

contract DeploySIP15ZoneWithCastWallet is Script {
Expand Down Expand Up @@ -89,7 +86,33 @@ contract DeploySIP15ZoneWithCastWallet is Script {

}

function _deploy() internal {
new SIP15Zone();
}
}
// source .env && forge script script/DeploySIP15Zone.s.sol:DeployAnvil --with-gas-price 2000000000 -vvvvv --rpc-url $ANVIL_RPC --broadcast
contract DeployAnvil is Script{
uint256 internal _privateKey;
address public deployer;
address public vault721;

function run() public {
_loadPrivateKeys();

vm.startBroadcast(_privateKey);
address zoneAddress = address(new SIP15Zone());
address vault721Adapter = address(new Vault721Adapter(IVault721(vault721)));
vm.stopBroadcast();
console2.log('Zone Deployed at: ', zoneAddress);
console2.log('vault721Adapter Deployed at: ', vault721Adapter);
}

function _loadPrivateKeys() internal {

_privateKey = vm.envUint('ANVIL_ONE');
deployer = vm.addr(_privateKey);
vault721 = vm.envAddress('VAULT721_SEPOLIA_ADDRESS'); // SepoliaContracts.Vault721_Address;

console2.log('\n');
console2.log('deployer address:', deployer);
console2.log('deployer balance:', deployer.balance);
}

}
276 changes: 183 additions & 93 deletions script/createListing.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,106 @@
import { BytesLike, ethers } from 'ethers';
import { AddressLike, BigNumberish, BytesLike, ParamType, ethers } from "ethers";
import {
VAULT721_SEPOLIA_ADDRESS,
VAULT721_SEPOLIA_ADAPATER_ADDRESS,
SIP15_ZONE_SEPOLIA_ADDRESS,
ANVIL_ONE,
ANVIL_RPC,
ARB_SEPOLIA_RPC,
WALLET_PRIV_KEY
} from './utils/constants';
const vault721AdapterABI = require('../out/Vault721Adapter.sol/Vault721Adapter.json');
const sip15ZoneABI = require('../out/SIP15Zone.sol/SIP15Zone.json');
VAULT721_SEPOLIA_ADDRESS,
VAULT721_ANVIL_ADDRESS,
VAULT721_SEPOLIA_ADAPATER_ADDRESS,
VAULT721_ANVIL_ADAPATER_ADDRESS,
SIP15_ZONE_SEPOLIA_ADDRESS,
ANVIL_ONE,
ANVIL_RPC,
ARB_SEPOLIA_RPC,
WALLET_PRIV_KEY,
ENCODING_HELPER,
ENCODING_HELPER_ANVIL,
} from "./utils/constants";
const vault721AdapterABI = require("../out/Vault721Adapter.sol/Vault721Adapter.json");
const EncodeSubstandard5ForEthersABI = require("../out/EncodeSubstandard5ForEthers.sol/EncodeSubstandard5ForEthers.json");
import { ItemType } from "@opensea/seaport-js/src/constants";
import { CreateOrderInput } from '@opensea/seaport-js/lib/types';
import { CreateOrderInput } from "@opensea/seaport-js/lib/types";
import { Seaport } from "@opensea/seaport-js";
import { Wallet, Provider } from 'ethers';
import {Vault721Adapter} from '../types/ethers-contracts/index';
import { Wallet, Provider, AbiCoder } from "ethers";
import {
Vault721Adapter,
EncodeSubstandard5ForEthers,
} from "../types/ethers-contracts/index";
import { Address } from "cluster";

const createSIP15ZoneListing = async (chain: string) => {
let provider: Provider;
let wallet: Wallet;
let seaport: Seaport;
if(chain == 'anvil'){
provider = new ethers.JsonRpcProvider(ANVIL_RPC);
wallet = new ethers.Wallet(
ANVIL_ONE as string,
provider
);
seaport = new Seaport(wallet);
} else if (chain == 'sepolia'){
provider = new ethers.JsonRpcProvider(ARB_SEPOLIA_RPC);
wallet = new ethers.Wallet(
WALLET_PRIV_KEY as string,
provider
);
seaport = new Seaport(wallet);
let provider: Provider;
let wallet: Wallet;
let seaport: Seaport;
let encodeSubstandard5Helper: EncodeSubstandard5ForEthers;
let vault721AdapterAddress: AddressLike;
let vault721Address: AddressLike;

if (chain == "anvil") {
provider = new ethers.JsonRpcProvider(ANVIL_RPC);
wallet = new ethers.Wallet(ANVIL_ONE as string, provider);
seaport = new Seaport(wallet);
if (VAULT721_ANVIL_ADAPATER_ADDRESS && VAULT721_ANVIL_ADDRESS) {
vault721AdapterAddress = VAULT721_ANVIL_ADAPATER_ADDRESS;
vault721Address = VAULT721_ANVIL_ADDRESS;
} else {
throw new Error("VAULT721_ANVIL_ADAPATER_ADDRESS undefined");
}

if (ENCODING_HELPER_ANVIL == undefined) {
const encodeSubstandard5Factory = new ethers.ContractFactory(
EncodeSubstandard5ForEthersABI.abi,
EncodeSubstandard5ForEthersABI.bytecode,
wallet
);
encodeSubstandard5Helper =
(await encodeSubstandard5Factory.deploy()) as EncodeSubstandard5ForEthers;
} else {
encodeSubstandard5Helper = new ethers.Contract(
ENCODING_HELPER_ANVIL,
EncodeSubstandard5ForEthersABI.abi,
wallet
) as unknown as EncodeSubstandard5ForEthers;
}
} else if (chain == "sepolia") {
provider = new ethers.JsonRpcProvider(ARB_SEPOLIA_RPC);
wallet = new ethers.Wallet(WALLET_PRIV_KEY as string, provider);
seaport = new Seaport(wallet);

if (VAULT721_SEPOLIA_ADAPATER_ADDRESS && VAULT721_SEPOLIA_ADDRESS) {
vault721AdapterAddress = VAULT721_SEPOLIA_ADAPATER_ADDRESS;
vault721Address = VAULT721_SEPOLIA_ADDRESS;
} else {
throw new Error("VAULT721_SEPOLIA_ADAPATER_ADDRESS undefined");
}

// if no helper exists deploy helper
if (!ENCODING_HELPER) {
const encodeSubstandard5Factory = new ethers.ContractFactory(
EncodeSubstandard5ForEthersABI.abi,
EncodeSubstandard5ForEthersABI.bytecode,
wallet
);
encodeSubstandard5Helper =
(await encodeSubstandard5Factory.deploy()) as EncodeSubstandard5ForEthers;
} else {
throw new Error('unsupported chain');
encodeSubstandard5Helper = new ethers.Contract(
ENCODING_HELPER,
EncodeSubstandard5ForEthersABI.abi,
wallet
) as unknown as EncodeSubstandard5ForEthers;
}
} else {
throw new Error("unsupported chain");
}

// TODO: Fill in the token address and token ID of the NFT you want to sell, as well as the price
let considerationTokenAddress: string = "";
let vaultId: string = "1";
let listingAmount: string = ethers.parseEther('1').toString();
const vault721Adapter = new ethers.Contract(VAULT721_SEPOLIA_ADAPATER_ADDRESS!, vault721AdapterABI.abi, wallet) as unknown as Vault721Adapter;
const sip15Zone = new ethers.Contract(SIP15_ZONE_SEPOLIA_ADDRESS!, sip15ZoneABI.abi);
// TODO: Fill in the token address and token ID of the NFT you want to sell, as well as the price
let considerationTokenAddress: string = "";
let vaultId: string = "1";
let listingAmount: string = ethers.parseEther("1").toString();
const vault721Adapter = new ethers.Contract(
vault721AdapterAddress,
vault721AdapterABI.abi,
wallet
) as unknown as Vault721Adapter;

/**
/**
* struct Substandard5Comparison {
uint8[] comparisonEnums;
address token;
Expand All @@ -55,65 +110,100 @@ const createSIP15ZoneListing = async (chain: string) => {
bytes32[] traitKeys;
}
*/
const substandard5ComparisonTypeString =
'Substandard5Comparison(uint8[] comparisonEnums,address token,address traits,uint256 identifier,bytes32[] traitValues,bytes32[] traitKeys)'
const substandard5ComparisonTypeString: readonly string[] = [
"tuple(uint8[] comparisonEnums,address token,address traits,uint256 identifier,bytes32[] traitValues,bytes32[] traitKeys)",
];
const substandard5ComparisonAbi = [
{
type: "tuple[]",
name: "Substandard5Comparison",
components: [
{ name: "comparisonEnums", type: "uint8[]" },
{ name: "token", type: "address" },
{ name: "traits", type: "address" },
{ name: "identifier", type: "uint256" },
{ name: "traitValues", type: "bytes32[]" },
{ name: "traitKeys", type: "bytes32[]" },
],
},
];
const _comparisonEnums: BigNumberish[] = new Uint8Array([4, 5]) as unknown as BigNumberish[];
const _traitKeys: BytesLike[] = [
ethers.keccak256(ethers.toUtf8Bytes("DEBT")),
ethers.keccak256(ethers.toUtf8Bytes("COLLATERAL")),
];
const _traitValues: BytesLike[] = await vault721Adapter.getTraitValues(
ethers.toBigInt(vaultId),
_traitKeys
);
console.log(_traitValues);
const substandard5data: any = [
{
comparisonEnums: _comparisonEnums,
token: VAULT721_SEPOLIA_ADDRESS,
traits: VAULT721_SEPOLIA_ADAPATER_ADDRESS,
identifier: vaultId,
traitValues: _traitValues,
traitKeys: _traitKeys,
},
];

const _comparisonEnums: number[] = [4, 5];
const _traitKeys: BytesLike[] = [ethers.keccak256(ethers.toUtf8Bytes('DEBT')), ethers.keccak256(ethers.toUtf8Bytes('COLLATERAL'))];
const _traitValues: BytesLike[] = await vault721Adapter.getTraitValues(ethers.toBigInt(vaultId), _traitKeys);

const substandard5data = {
comparisonEnums: _comparisonEnums,
token: VAULT721_SEPOLIA_ADDRESS,
traits: VAULT721_SEPOLIA_ADAPATER_ADDRESS,
identifier: vaultId,
traitValues: _traitValues,
traitKeys: _traitKeys
}
//encode data with struct fragment as type
const encodedStruct = ethers.solidityPacked([substandard5ComparisonTypeString], [substandard5data]);
//encode extraData with substandard
const extraData = ethers.solidityPacked(['uint8', 'bytes'], [ethers.toBeHex('0x05'), encodedStruct]);
// get zone hash by hashing extraData
const zoneHash = ethers.keccak256(extraData);
const timeStamp = (await provider.getBlock('latest'))!.timestamp;
//create encoded substandard 5 data with helper
const extraData = await encodeSubstandard5Helper.encodeSubstandard5(
_comparisonEnums,
vault721Address,
vault721AdapterAddress,
vaultId,
_traitValues,
_traitKeys
);

const createOrderInput: CreateOrderInput = {
offer: [
{
itemType: ItemType.ERC721,
token: VAULT721_SEPOLIA_ADDRESS!,
identifier: vaultId
},
],
consideration: [
{
token: considerationTokenAddress,
amount: ethers.parseEther(listingAmount).toString()
},
],
startTime: timeStamp,
endTime: 10,
zoneHash: zoneHash,
zone: SIP15_ZONE_SEPOLIA_ADDRESS,
restrictedByZone: true,
}
// get zone hash by hashing extraData
const zoneHash = ethers.keccak256(extraData);
const timeStamp = (await provider.getBlock("latest"))!.timestamp;

try {
const { executeAllActions } = await seaport.createOrder(createOrderInput, wallet.address);
const order = await executeAllActions();
console.log("Successfully created a listing with orderHash:", order.parameters);
} catch (error) {
console.error("Error in createListing:", error);
}
}
const createOrderInput: CreateOrderInput = {
offer: [
{
itemType: ItemType.ERC721,
token: VAULT721_SEPOLIA_ADDRESS!,
identifier: vaultId,
},
],
consideration: [
{
token: considerationTokenAddress,
amount: ethers.parseEther(listingAmount).toString(),
},
],
startTime: timeStamp,
endTime: 10,
zoneHash: zoneHash,
zone: SIP15_ZONE_SEPOLIA_ADDRESS,
restrictedByZone: true,
};

try {
const { executeAllActions } = await seaport.createOrder(
createOrderInput,
wallet.address
);
const order = await executeAllActions();
console.log(
"Successfully created a listing with orderHash:",
order.parameters
);
} catch (error) {
console.error("Error in createListing:", error);
}
};

// Check if the module is the main entry point
if (require.main === module) {
// If yes, run the createOffer function
createSIP15ZoneListing('sepolia').catch((error) => {
console.error("Error in createListing:", error);
});
// If yes, run the createOffer function
createSIP15ZoneListing("anvil").catch((error) => {
console.error("Error in createListing:", error);
});
}

export default createSIP15ZoneListing;
export default createSIP15ZoneListing;
Loading

0 comments on commit 09ce5d1

Please sign in to comment.