Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preparation of transactions #13

Merged
merged 8 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ gas-report.txt
typechain-types
coverage
coverage.json
contracts
contracts
.env
105 changes: 105 additions & 0 deletions scripts/testnet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Wallet } from "ethers"
import {
VaultManager,
LockDealNFT,
DealProvider,
LockDealProvider,
TimedDealProvider,
CollateralProvider,
RefundProvider,
SimpleBuilder,
SimpleRefundBuilder,
ERC20Token,
} from "../typechain-types"
import { deployFrom, setTrustee, approveContracts, createNewVault, approveToken } from "./utility/manageable"
import { createSimpleNFT, createRefundNFT } from "./utility/creation"
import { amount, startTime, finishTime, password, provider } from "./utility/constants"
import { _withdrawPools, _splitPools } from "./utility/control"
import { createMassSimplePools, createMassRefundPools } from "./utility/builders"

let vaultManager: VaultManager,
lockDealNFT: LockDealNFT,
dealProvider: DealProvider,
lockProvider: LockDealProvider,
timedProvider: TimedDealProvider,
collateralProvider: CollateralProvider,
refundProvider: RefundProvider,
simpleBuilder: SimpleBuilder,
simpleRefundBuilder: SimpleRefundBuilder,
token: ERC20Token,
mainCoin: ERC20Token

async function main() {
try {
const user = new Wallet(password.toString(), provider)
await deploy(user)
await setup(user)
const ids = await createPools(user)
await splitPools(user, ids)
await withdrawPools(user, ids)
await createMassSimplePools(user, simpleBuilder, vaultManager, dealProvider.address, token)
await createMassRefundPools(user, simpleRefundBuilder, vaultManager, dealProvider.address, token, mainCoin)
} catch (error) {
console.error("Error in main:", error)
}
}

async function deploy(user: Wallet) {
vaultManager = await deployFrom("VaultManager", user)
lockDealNFT = await deployFrom("LockDealNFT", user, vaultManager.address, "")
dealProvider = await deployFrom("DealProvider", user, lockDealNFT.address)
lockProvider = await deployFrom("LockDealProvider", user, lockDealNFT.address, dealProvider.address)
timedProvider = await deployFrom("TimedDealProvider", user, lockDealNFT.address, lockProvider.address)
collateralProvider = await deployFrom("CollateralProvider", user, lockDealNFT.address, dealProvider.address)
refundProvider = await deployFrom("RefundProvider", user, lockDealNFT.address, collateralProvider.address)
simpleBuilder = await deployFrom("SimpleBuilder", user, lockDealNFT.address)
simpleRefundBuilder = await deployFrom(
"SimpleRefundBuilder",
user,
lockDealNFT.address,
refundProvider.address,
collateralProvider.address
)
token = await deployFrom("ERC20Token", user, "Test Token", "TT")
mainCoin = await deployFrom("ERC20Token", user, "USDT", "TT")
}

async function setup(user: Wallet) {
await setTrustee(vaultManager, user, lockDealNFT.address)
await approveContracts(user, lockDealNFT, [
dealProvider,
lockProvider,
timedProvider,
collateralProvider,
refundProvider,
simpleBuilder,
simpleRefundBuilder,
])
await createNewVault(vaultManager, user, token)
await createNewVault(vaultManager, user, mainCoin)
await approveToken(token, user, vaultManager.address)
await approveToken(mainCoin, user, vaultManager.address)
console.log("Setup done")
}

async function createPools(user: Wallet): Promise<number[]> {
const id = parseInt((await lockDealNFT.totalSupply()).toString())
await createSimpleNFT(user, dealProvider, vaultManager, token, [amount])
await createSimpleNFT(user, lockProvider, vaultManager, token, [amount, startTime])
await createSimpleNFT(user, timedProvider, vaultManager, token, [amount, startTime, finishTime])
await createRefundNFT(user, refundProvider, timedProvider, vaultManager, token, mainCoin)
// IDs are always [id, id + 1...] every time the script is run
return [id, id + 1, id + 2, id + 3]
}

async function splitPools(user: Wallet, ids: number[]) {
await _splitPools(user, lockDealNFT, ids)
console.log("Split NFTs")
}

async function withdrawPools(user: Wallet, ids: number[]) {
await _withdrawPools(user, lockDealNFT, ids)
console.log("Withdraw NFTs")
}

main()
69 changes: 69 additions & 0 deletions scripts/utility/builders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Wallet } from "ethers"
import { gasLimit, gasPrice, amount } from "./constants"
import { SimpleBuilder, SimpleRefundBuilder, ERC20Token, VaultManager } from "../../typechain-types"
import { getSignature } from "./creation"
import { BuilderState } from "../../typechain-types/contracts/LockDealNFT/contracts/Builders/SimpleBuilder/SimpleBuilder"
import { finishTime } from "./constants"

const sendData: BuilderState.BuilderStruct = {
userPools: [
{ user: "0xf7f1f00b13F4c3D818f052498902067aB91a3A66", amount: amount },
{ user: "0xf7f1f00b13F4c3D818f052498902067aB91a3A66", amount: amount },
{ user: "0xf7f1f00b13F4c3D818f052498902067aB91a3A66", amount: amount },
{ user: "0x6063fBa0fBd645d648C129854Cce45A70dd89691", amount: amount },
{ user: "0x6063fBa0fBd645d648C129854Cce45A70dd89691", amount: amount },
{ user: "0x6063fBa0fBd645d648C129854Cce45A70dd89691", amount: amount },
{ user: "0xf7f1f00b13F4c3D818f052498902067aB91a3A66", amount: amount },
{ user: "0xf7f1f00b13F4c3D818f052498902067aB91a3A66", amount: amount },
{ user: "0xf7f1f00b13F4c3D818f052498902067aB91a3A66", amount: amount },
],
totalAmount: amount.mul(9),
}

export async function createMassSimplePools(
user: Wallet,
simpleBuilder: SimpleBuilder,
vaultManager: VaultManager,
provider: string,
token: ERC20Token
) {
const tx = await simpleBuilder
.connect(user)
.buildMassPools(
[provider, token.address],
sendData,
[],
getSignature(user, vaultManager, token, token.address, amount.mul(9)),
{
gasLimit,
gasPrice,
}
)
await tx.wait()
console.log("Mass simple NFTs created")
}

export async function createMassRefundPools(
user: Wallet,
simpleRefundBuilder: SimpleRefundBuilder,
vaultManager: VaultManager,
provider: string,
token: ERC20Token,
mainCoin: ERC20Token
) {
const tx = await simpleRefundBuilder
.connect(user)
.buildMassPools(
[provider, token.address, mainCoin.address],
sendData,
[[amount.mul(3), finishTime], []],
getSignature(user, vaultManager, token, token.address, amount.mul(9)),
getSignature(user, vaultManager, token, mainCoin.address, amount.mul(3)),
{
gasLimit,
gasPrice,
}
)
await tx.wait()
console.log("Mass refund NFTs created")
}
14 changes: 14 additions & 0 deletions scripts/utility/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import "dotenv/config"
import { BigNumber } from "ethers"
import { ethers } from "hardhat"

export const gasLimit = 30_000_000
export const gasPrice = ethers.utils.parseUnits("5", "gwei")
export const unixTime = BigNumber.from(Math.floor(Date.now() / 1000))
export const week = 60 * 60 * 24 * 7
export const startTime = unixTime.add(1000)
export const finishTime = unixTime.add(week).mul(2)
export const amount = ethers.utils.parseUnits("100", 8)
export const password = process.env.PASSWORD ?? ""
export const networkRPC = "https://bsc-testnet.publicnode.com"
export const provider = new ethers.providers.JsonRpcProvider(networkRPC)
30 changes: 30 additions & 0 deletions scripts/utility/control.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Wallet } from "ethers"
import { ethers } from "hardhat"
import { LockDealNFT } from "../../typechain-types"
import { gasLimit, gasPrice } from "./constants"

export async function _splitPools(user: Wallet, lockDealNFT: LockDealNFT, ids: number[]) {
const ratio = ethers.utils.parseUnits("5", 20) // 50%
const packedData = ethers.utils.defaultAbiCoder.encode(["uint256", "address"], [ratio, user.address])
for (const id of ids) {
const tx = await lockDealNFT
.connect(user)
["safeTransferFrom(address,address,uint256,bytes)"](user.address, lockDealNFT.address, id, packedData, {
gasLimit,
gasPrice,
})
await tx.wait()
}
}

export async function _withdrawPools(user: Wallet, lockDealNFT: LockDealNFT, ids: number[]) {
for (const id of ids) {
const tx = await lockDealNFT
.connect(user)
["safeTransferFrom(address,address,uint256)"](user.address, lockDealNFT.address, id, {
gasLimit,
gasPrice,
})
await tx.wait()
}
}
69 changes: 69 additions & 0 deletions scripts/utility/creation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
DealProvider,
LockDealProvider,
TimedDealProvider,
RefundProvider,
VaultManager,
ERC20Token,
} from "../../typechain-types"
import { Wallet, BigNumber } from "ethers"
import { ethers } from "hardhat"
import { gasLimit, gasPrice, startTime, finishTime, amount } from "./constants"

async function createSimpleNFT(
user: Wallet,
provider: DealProvider | LockDealProvider | TimedDealProvider,
vaultManager: VaultManager,
token: ERC20Token,
poolParams: BigNumber[]
) {
const userAddress: string = await user.address
const tokenSignature = await getSignature(user, vaultManager, token, token.address)
const tx = await provider
.connect(user)
.createNewPool([userAddress, token.address], [...poolParams], tokenSignature, {
gasLimit,
gasPrice,
})
await tx.wait()
const name = await provider.name()
console.log(name + ` NFT created`)
}

async function createRefundNFT(
user: Wallet,
refundProvider: RefundProvider,
provider: DealProvider | LockDealProvider | TimedDealProvider,
vaultManager: VaultManager,
token: ERC20Token,
mainCoin: ERC20Token
) {
const name = await refundProvider.name()
const tokenSignature = await getSignature(user, vaultManager, token, token.address)
const mainCoinsignature = await getSignature(user, vaultManager, token, mainCoin.address)
const addresses = [user.address, token.address, mainCoin.address, provider.address]
const params = [amount, startTime, finishTime, amount, finishTime]
const tx = await refundProvider
.connect(user)
.createNewRefundPool(addresses, params, tokenSignature, mainCoinsignature, { gasLimit, gasPrice })
await tx.wait()
console.log(name + ` NFT created`)
}

async function getSignature(
user: Wallet,
vaultManager: VaultManager,
token: ERC20Token,
tokenAddress: string = token.address,
tokenAmount: BigNumber = amount
) {
const dataToCheck = ethers.utils.solidityPack(["address", "uint256"], [tokenAddress, tokenAmount])
const currentNonce = await vaultManager.nonces(user.address)
const hash = ethers.utils.solidityKeccak256(
["bytes", "uint"],
[dataToCheck, tokenAddress == token.address ? currentNonce : currentNonce.add(1)]
)
return await user.signMessage(ethers.utils.arrayify(hash))
}

export { createSimpleNFT, createRefundNFT, getSignature }
42 changes: 42 additions & 0 deletions scripts/utility/manageable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Wallet, constants } from "ethers"
import { ERC20Token, LockDealNFT, VaultManager } from "../../typechain-types"
import { ethers } from "hardhat"
import { gasLimit, gasPrice } from "./constants"

async function deployFrom<T>(contractName: string, user: Wallet, ...args: string[]): Promise<T> {
const Contract = await ethers.getContractFactory(contractName, user)
const contract = await Contract.connect(user).deploy(...args)
console.log(`Deploying ${contractName}...`)
return contract.deployed() as Promise<T>
}

async function setTrustee(vaultManager: VaultManager, user: Wallet, address: string) {
const tx = await vaultManager.connect(user).setTrustee(address, { gasLimit, gasPrice })
await tx.wait()
}

async function approveContracts(user: Wallet, lockDealNFT: LockDealNFT, contracts: any[]) {
for (const contract of contracts) {
await approveContract(user, lockDealNFT, contract)
}
}

async function createNewVault(vaultManager: VaultManager, user: Wallet, token: ERC20Token) {
const tx = await vaultManager.connect(user)["createNewVault(address)"](token.address, { gasLimit, gasPrice })
await tx.wait()
}

async function approveToken(token: ERC20Token, user: Wallet, spender: string) {
const tx = await token.connect(user).approve(spender, constants.MaxUint256, { gasLimit, gasPrice })
await tx.wait()
}

async function approveContract(user: Wallet, lockDealNFT: LockDealNFT, contract: any) {
const tx = await lockDealNFT.connect(user).setApprovedContract(contract.address, true, {
gasLimit: gasLimit,
gasPrice: gasPrice,
})
await tx.wait()
}

export { deployFrom, setTrustee, approveContracts, createNewVault, approveToken, approveContract }
5 changes: 4 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"types": ["hardhat", "node"],
"target": "es2020",
"module": "commonjs",
"moduleResolution": "node",
Expand All @@ -8,5 +9,7 @@
"strict": true,
"skipLibCheck": true,
"resolveJsonModule": true
}
},
"include": ["./test", "./src", "./scripts"],
"files": ["./hardhat.config.ts"]
}