ethereum-waffle#deployContract TypeScript Examples
The following examples show how to use
ethereum-waffle#deployContract.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: e2e.test.ts From bodhi.js with Apache License 2.0 | 6 votes |
describe('e2e test', () => {
let wallet: Signer;
let walletTo: Signer;
before(async () => {
[wallet, walletTo] = await provider.getWallets();
});
after(async () => {
provider.api.disconnect();
});
it('evm block number', async () => {
let contract = await deployContract(wallet as any, BlockNumberTest);
let current_block_number = Number(await provider.api.query.system.number());
let height = await contract.currentBlock();
expect(await height.toString()).to.eq(current_block_number.toString());
});
});
Example #2
Source File: fixtures.ts From vvs-swap-core with GNU General Public License v3.0 | 6 votes |
export async function pairFixture([wallet]: Wallet[], provider: Web3Provider): Promise<PairFixture> {
const { factory } = await factoryFixture([wallet], provider)
const tokenA = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides)
const tokenB = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides)
await factory.createPair(tokenA.address, tokenB.address, overrides)
const pairAddress = await factory.getPair(tokenA.address, tokenB.address)
const pair = new Contract(pairAddress, JSON.stringify(VVSPair.abi), provider).connect(wallet)
const token0Address = (await pair.token0()).address
const token0 = tokenA.address === token0Address ? tokenA : tokenB
const token1 = tokenA.address === token0Address ? tokenB : tokenA
return { factory, token0, token1, pair }
}
Example #3
Source File: fixtures.ts From staking-factory with MIT License | 6 votes |
export async function stakingRewardsFactoryFixture(
[wallet]: Wallet[],
provider: providers.Web3Provider
): Promise<StakingRewardsFactoryFixture> {
const rewardsToken = await deployContract(wallet, TestERC20, [expandTo18Decimals(1_000_000_000)])
// deploy staking tokens
const stakingTokens = []
for (let i = 0; i < NUMBER_OF_STAKING_TOKENS; i++) {
const stakingToken = await deployContract(wallet, TestERC20, [expandTo18Decimals(1_000_000_000)])
stakingTokens.push(stakingToken)
}
// deploy the staking rewards factory
const { timestamp: now } = await provider.getBlock('latest')
const genesis = now + 60 * 60
const rewardAmounts: BigNumber[] = new Array(stakingTokens.length).fill(expandTo18Decimals(10))
const stakingRewardsFactory = await deployContract(wallet, StakingRewardsFactory, [rewardsToken.address, genesis])
return { rewardsToken, stakingTokens, genesis, rewardAmounts, stakingRewardsFactory }
}
Example #4
Source File: fixtures.ts From staking-factory with MIT License | 6 votes |
export async function stakingRewardsFixture([wallet]: Wallet[]): Promise<StakingRewardsFixture> {
const rewardsDistribution = wallet.address
const rewardsToken = await deployContract(wallet, TestERC20, [expandTo18Decimals(1000000)])
const stakingToken = await deployContract(wallet, UniswapV2ERC20, [expandTo18Decimals(1000000)])
const stakingRewards = await deployContract(wallet, StakingRewards, [
rewardsDistribution,
rewardsToken.address,
stakingToken.address,
])
return { stakingRewards, rewardsToken, stakingToken }
}
Example #5
Source File: ExampleOracleSimple.spec.ts From pancake-swap-testnet with MIT License | 6 votes |
describe('ExampleOracleSimple', () => {
const provider = new MockProvider({
hardfork: 'istanbul',
mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
gasLimit: 9999999
})
const [wallet] = provider.getWallets()
const loadFixture = createFixtureLoader(provider, [wallet])
let token0: Contract
let token1: Contract
let pair: Contract
let exampleOracleSimple: Contract
async function addLiquidity() {
await token0.transfer(pair.address, token0Amount)
await token1.transfer(pair.address, token1Amount)
await pair.mint(wallet.address, overrides)
}
beforeEach(async function() {
const fixture = await loadFixture(v2Fixture)
token0 = fixture.token0
token1 = fixture.token1
pair = fixture.pair
await addLiquidity()
exampleOracleSimple = await deployContract(
wallet,
ExampleOracleSimple,
[fixture.factoryV2.address, token0.address, token1.address],
overrides
)
})
it('update', async () => {
const blockTimestamp = (await pair.getReserves())[2]
await mineBlock(provider, blockTimestamp + 60 * 60 * 23)
await expect(exampleOracleSimple.update(overrides)).to.be.reverted
await mineBlock(provider, blockTimestamp + 60 * 60 * 24)
await exampleOracleSimple.update(overrides)
const expectedPrice = encodePrice(token0Amount, token1Amount)
expect(await exampleOracleSimple.price0Average()).to.eq(expectedPrice[0])
expect(await exampleOracleSimple.price1Average()).to.eq(expectedPrice[1])
expect(await exampleOracleSimple.consult(token0.address, token0Amount)).to.eq(token1Amount)
expect(await exampleOracleSimple.consult(token1.address, token1Amount)).to.eq(token0Amount)
})
})
Example #6
Source File: fixtures.ts From pancake-swap-testnet with MIT License | 6 votes |
export async function pairFixture(provider: Web3Provider, [wallet]: Wallet[]): Promise<PairFixture> {
const { factory } = await factoryFixture(provider, [wallet])
const tokenA = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides)
const tokenB = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides)
await factory.createPair(tokenA.address, tokenB.address, overrides)
const pairAddress = await factory.getPair(tokenA.address, tokenB.address)
const pair = new Contract(pairAddress, JSON.stringify(PancakePair.abi), provider).connect(wallet)
const token0Address = (await pair.token0()).address
const token0 = tokenA.address === token0Address ? tokenA : tokenB
const token1 = tokenA.address === token0Address ? tokenB : tokenA
return { factory, token0, token1, pair }
}
Example #7
Source File: deployMulticall.ts From useDApp with MIT License | 6 votes |
deployMulticall = async (provider: MockProvider, chainId: number) => {
const multicall = await deployContract((await provider.getWallets())[0], {
bytecode: MultiCall.bytecode,
abi: MultiCall.abi,
})
const multicallAddresses = { [chainId]: multicall.address }
return multicallAddresses
}
Example #8
Source File: fixtures.ts From apeswap-swap-core with GNU General Public License v3.0 | 6 votes |
export async function pairFixture([wallet]: Wallet[], provider: Web3Provider): Promise<PairFixture> {
const { factory } = await factoryFixture([wallet], provider)
const tokenA = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides)
const tokenB = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides)
await factory.createPair(tokenA.address, tokenB.address, overrides)
const pairAddress = await factory.getPair(tokenA.address, tokenB.address)
const pair = new Contract(pairAddress, JSON.stringify(ApePair.abi), provider).connect(wallet)
const token0Address = (await pair.token0()).address
const token0 = tokenA.address === token0Address ? tokenA : tokenB
const token1 = tokenA.address === token0Address ? tokenB : tokenA
return { factory, token0, token1, pair }
}
Example #9
Source File: HelloWorld.test.ts From bodhi.js with Apache License 2.0 | 6 votes |
describe('HelloWorld', () => {
let wallet: Signer;
let instance: Contract;
before(async () => {
[wallet] = await provider.getWallets();
instance = await deployContract(wallet, HelloWorld);
});
after(async () => {
provider.api.disconnect();
});
it('returns the right value after the contract is deployed', async () => {
console.log(instance.address);
expect(await instance.helloWorld()).to.equal('Hello World!');
});
});
Example #10
Source File: fixtures.ts From apeswap-swap-core with GNU General Public License v3.0 | 5 votes |
export async function factoryFixture([wallet]: Wallet[], _: Web3Provider): Promise<FactoryFixture> {
const factory = await deployContract(wallet, ApeFactory, [wallet.address], overrides)
return { factory }
}
Example #11
Source File: fixtures.ts From vvs-swap-core with GNU General Public License v3.0 | 5 votes |
export async function factoryFixture([wallet]: Wallet[], _: Web3Provider): Promise<FactoryFixture> {
const factory = await deployContract(wallet, VVSFactory, [wallet.address], overrides)
return { factory }
}
Example #12
Source File: deployMockToken.tsx From useDApp with MIT License | 5 votes |
export async function deployMockToken(deployer: Wallet, initialBalance?: BigNumber) {
const args = ['MOCKToken', 'MOCK', deployer.address, initialBalance ?? MOCK_TOKEN_INITIAL_BALANCE]
return await deployContract(deployer, ERC20Mock, args)
}
Example #13
Source File: sortition-sum-tree-factory.test.ts From sortition-sum-tree-factory with MIT License | 5 votes |
describe('SortitionSumTreeFactory', () =>
it('Should successfully keep track of ID ownership of values and draw them from the tree appropriately.', async () => {
// Deploy contract
const sortitionSumTreeFactory = await deployContract(wallet, ExposedSortitionSumTreeFactory)
// Create tree and populate with 4 candidates
const tree = { key: ethers.utils.formatBytes32String('1'), K: 2 }
const candidates = {
bob: {
ID:
'0x0000000000000000000000000000000000000000000000000000000000000002',
value: 15
},
dave: {
ID:
'0x0000000000000000000000000000000000000000000000000000000000000004',
value: 5
},
alice: {
ID:
'0x0000000000000000000000000000000000000000000000000000000000000001',
value: 10
},
carl: {
ID:
'0x0000000000000000000000000000000000000000000000000000000000000003',
value: 20
}
}
await sortitionSumTreeFactory._createTree(tree.key, tree.K)
for (const candidate of Object.values(candidates)) {
await sortitionSumTreeFactory._set(
tree.key,
candidate.value,
candidate.ID
)
}
// Test drawing Bob with 13 and Carl with 27
expect(await sortitionSumTreeFactory._draw(tree.key, 13)).to.equal(
candidates.bob.ID
)
expect(await sortitionSumTreeFactory._draw(tree.key, 27)).to.equal(
candidates.carl.ID
)
// Set Alice to 14 to draw her with 13 and then set her back to 10 to draw Bob again
await sortitionSumTreeFactory._set(tree.key, 14, candidates.alice.ID)
expect(await sortitionSumTreeFactory._draw(tree.key, 13)).to.equal(
candidates.alice.ID
)
await sortitionSumTreeFactory._set(tree.key, 10, candidates.alice.ID)
expect(await sortitionSumTreeFactory._draw(tree.key, 13)).to.equal(
candidates.bob.ID
)
// Remove Carl to draw Dave with 27 and add him back in to draw him again
await sortitionSumTreeFactory._set(tree.key, 0, candidates.carl.ID)
expect(await sortitionSumTreeFactory._draw(tree.key, 27)).to.equal(
candidates.dave.ID
)
await sortitionSumTreeFactory._set(
tree.key,
candidates.carl.value,
candidates.carl.ID
)
expect(await sortitionSumTreeFactory._draw(tree.key, 27)).to.equal(
candidates.carl.ID
)
// Test stake view
for (const candidate of Object.values(candidates))
expect(
await sortitionSumTreeFactory._stakeOf(tree.key, candidate.ID)
).to.deep.equal(ethers.utils.bigNumberify(candidate.value))
})
)
Example #14
Source File: sequencer-batch-append.spec.ts From integration-tests with MIT License | 5 votes |
describe('Queue Origin Sequencer Transactions', () => {
let optimismProvider
let provider: JsonRpcProvider
let token
let signer
before(async () => {
const web3 = new Web3Provider(
ganache.provider({
mnemonic: Config.Mnemonic(),
})
)
optimismProvider = new OptimismProvider(Config.L2NodeUrlWithPort(), web3)
provider = new JsonRpcProvider(Config.L2NodeUrlWithPort())
})
const initalSupply = 1000
before(async () => {
const pre = await provider.getBlock('latest')
signer = await provider.getSigner()
token = await deployContract(signer, ERC20, [initalSupply, 'Foo', 8, 'FOO'])
// Allow the batch to be submitted
do {
const tip = await provider.getBlock('latest')
await sleep(5000)
if (tip.number === pre.number + 1) {
break
}
} while (true)
})
it('should sequencer batch append', async () => {
const chainId = await signer.getChainId()
const address = await signer.getAddress()
const nonce = await provider.getTransactionCount(address)
const result = await token.transfer(etherbase, 1)
const receipt = await result.wait()
assert(receipt)
})
})
Example #15
Source File: BasicToken.test.ts From bodhi.js with Apache License 2.0 | 5 votes |
describe('BasicToken', () => {
let wallet: Signer;
let walletTo: Signer;
let emptyWallet: Signer;
let token: Contract;
before(async () => {
[wallet, walletTo, emptyWallet] = await provider.getWallets();
token = await deployContract(wallet, BasicToken, [1000]);
});
after(async () => {
provider.api.disconnect();
});
it('Assigns initial balance', async () => {
expect(await token.balanceOf(await wallet.getAddress())).to.equal(1000);
});
it('Transfer adds amount to destination account', async () => {
await token.transfer(await walletTo.getAddress(), 7);
expect(await token.balanceOf(await walletTo.getAddress())).to.equal(7);
});
it('Transfer emits event', async () => {
await expect(token.transfer(await walletTo.getAddress(), 7))
.to.emit(token, 'Transfer')
.withArgs(await wallet.getAddress(), await walletTo.getAddress(), 7);
});
it('Can not transfer above the amount', async () => {
await expect(token.transfer(await walletTo.getAddress(), 1007)).to.be.reverted;
});
it('Can not transfer from empty account', async () => {
if (!process.argv.includes('--with-ethereum-compatibility')) {
// If it is not called by the maintainer, developer, or contract, it needs to be deployed first
await provider.api.tx.evm.publishContract(token.address).signAndSend(testPairs.alice.address);
}
const tokenFromOtherWallet = token.connect(emptyWallet);
await expect(tokenFromOtherWallet.transfer(await wallet.getAddress(), 1)).to.be.reverted;
});
});
Example #16
Source File: fixtures.ts From pancake-swap-testnet with MIT License | 5 votes |
export async function factoryFixture(_: Web3Provider, [wallet]: Wallet[]): Promise<FactoryFixture> {
const factory = await deployContract(wallet, PancakeFactory, [wallet.address], overrides)
return { factory }
}
Example #17
Source File: Prices.test.ts From bodhi.js with Apache License 2.0 | 5 votes |
describe('Prices', () => {
let prices: Contract;
before(async () => {
const [wallet] = await provider.getWallets();
prices = await deployContract(wallet as any, Prices);
});
after(async () => {
provider.api.disconnect();
});
it('getPrice works', async () => {
await feedValues('RENBTC', BigNumber.from(34_500).mul(BigNumber.from(10).pow(18)).toString());
expect(await prices.getPrice(ADDRESS.RENBTC)).to.equal(
BigNumber.from(34_500).mul(BigNumber.from(10).pow(18)).toString()
);
await feedValues('RENBTC', BigNumber.from(33_800).mul(BigNumber.from(10).pow(18)).toString());
expect(await prices.getPrice(ADDRESS.RENBTC)).to.equal(
BigNumber.from(33_800).mul(BigNumber.from(10).pow(18)).toString()
);
await feedValues('DOT', BigNumber.from(15).mul(BigNumber.from(10).pow(18)).toString());
expect(await prices.getPrice(ADDRESS.DOT)).to.equal(BigNumber.from(15).mul(BigNumber.from(10).pow(18)).toString());
await feedValues('DOT', BigNumber.from(16).mul(BigNumber.from(10).pow(18)).toString());
expect(await prices.getPrice(ADDRESS.DOT)).to.equal(BigNumber.from(16).mul(BigNumber.from(10).pow(18)).toString());
expect(await prices.getPrice(ADDRESS.AUSD)).to.equal(BigNumber.from(1).mul(BigNumber.from(10).pow(18)).toString());
expect(await prices.getPrice(ADDRESS.KUSD)).to.equal(0);
});
it('ignores invalid address as CurrencyId::erc20', async () => {
// not system contract
expect(await prices.getPrice('0x1000000000000000000000000000000000000000')).to.equal(0);
// Zero address
await expect(prices.getPrice('0x0000000000000000000000000000000000000000')).to.be.reverted;
});
});
Example #18
Source File: EVM.test.ts From bodhi.js with Apache License 2.0 | 5 votes |
describe('EVM', () => {
let wallet: Signer;
let walletTo: Signer;
let evm: Contract;
let evmPredeployed: Contract;
before(async () => {
[wallet, walletTo] = await provider.getWallets();
evm = await deployContract(wallet as any, EVM);
evmPredeployed = new ethers.Contract(ADDRESS.EVM, EVM_ABI, wallet as any);
});
after(async () => {
provider.api.disconnect();
});
it('evm works', async () => {
if (!process.argv.includes('--with-ethereum-compatibility')) {
expect((await evm.newContractExtraBytes()).toString()).to.equal(formatAmount('10_000'));
expect((await evm.storageDepositPerByte()).toString()).to.equal(formatAmount('100_000_000_000_000'));
expect((await evm.developerDeposit()).toString()).to.equal(formatAmount('1_000_000_000_000_000_000'));
expect((await evm.publicationFee()).toString()).to.equal(formatAmount('1_000_000_000_000_000_000'));
await evmPredeployed.publishContract(evm.address);
} else {
expect(await evm.newContractExtraBytes()).to.equal(0);
expect(await evm.storageDepositPerByte()).to.equal(0);
expect(await evm.developerDeposit()).to.equal(0);
expect(await evm.publicationFee()).to.equal(0);
}
expect(await evm.maintainerOf(evm.address)).to.equal(await wallet.getAddress());
// The contract created by the user cannot be transferred through the contract,
// only through the evm dispatch call `transfer_maintainer`.
await expect(evm.transferMaintainer(evm.address, await walletTo.getAddress())).to.be.reverted;
await new Promise(async (resolve) => {
provider.api.tx.evm
.transferMaintainer(evm.address, await walletTo.getAddress())
.signAndSend(testPairs.alice.address, (result) => {
if (result.status.isFinalized || result.status.isInBlock) {
resolve(undefined);
}
});
});
expect(await evm.maintainerOf(evm.address)).to.equal(await walletTo.getAddress());
expect(await evm.developerStatus(await wallet.getAddress())).to.equal(false);
await evmPredeployed.developerEnable();
expect(await evm.developerStatus(await wallet.getAddress())).to.equal(true);
await evmPredeployed.developerDisable();
expect(await evm.developerStatus(await wallet.getAddress())).to.equal(false);
});
});
Example #19
Source File: AmmSpec2.ts From perpetual-protocol with GNU General Public License v3.0 | 5 votes |
describe("Amm Unit Test 2 (Waffle)", async () => {
const [wallet1, wallet2] = new MockProvider().getWallets()
let amm: Amm
let l2PriceFeed: MockContract
let quoteToken: MockContract
let clearingHouse: MockContract
const AmmArtifact = await artifacts.readArtifact(ContractFullyQualifiedName.Amm)
const IERC20Artifact = await artifacts.readArtifact(ContractFullyQualifiedName.IERC20)
const L2PriceFeedArtifact = await artifacts.readArtifact(ContractFullyQualifiedName.L2PriceFeed)
beforeEach(async () => {
quoteToken = await deployMockContract(wallet1, IERC20Artifact.abi)
clearingHouse = await deployMockContract(wallet1, [])
l2PriceFeed = await deployMockContract(wallet1, L2PriceFeedArtifact.abi)
amm = ((await deployContract(wallet1, AmmArtifact, [], { gasLimit: 6000000 })) as unknown) as Amm
await amm.initialize(
parseEther("1000"),
parseEther("100"),
parseEther("0.9"), // tradeLimitRatio
parseEther("3600"), // fundingPeriod - 1hr
l2PriceFeed.address,
utils.formatBytes32String("ETH"),
quoteToken.address,
BigNumber.from(0), // fluctuation
BigNumber.from(0), // toll
BigNumber.from(0), // spread
)
await amm.setCounterParty(clearingHouse.address)
amm.connect(clearingHouse.address)
})
describe("price", () => {
it("getUnderlyingPrice", async () => {
const price = parseEther("1")
const priceFeedKeyBytes32 = await amm.priceFeedKey()
const priceFeedKeyStr = utils.parseBytes32String(priceFeedKeyBytes32)
expect(priceFeedKeyStr).eq("ETH")
await l2PriceFeed.mock.getPrice.withArgs(priceFeedKeyBytes32).returns(price)
expect((await amm.getUnderlyingPrice()).d).deep.eq(price)
})
})
describe("setCap", () => {
it("change maxHoldingBaseAsset and openInterestNotionalCap", async () => {
await expect(amm.setCap({ d: 100 }, { d: 200 }))
.to.emit(amm, "CapChanged")
.withArgs("100", "200")
expect((await amm.getMaxHoldingBaseAsset()).d).deep.eq(BigNumber.from(100))
expect((await amm.getOpenInterestNotionalCap()).d).deep.eq(BigNumber.from(200))
})
})
describe("setPriceFeed", () => {
it("set priceFeed correctly", async () => {
const updatedPriceFeed = "0x77F9710E7d0A19669A13c055F62cd80d313dF022"
expect(await amm.priceFeed()).to.eq(l2PriceFeed.address)
await expect(amm.setPriceFeed(updatedPriceFeed))
.to.emit(amm, "PriceFeedUpdated")
.withArgs(updatedPriceFeed)
expect(await amm.priceFeed()).to.eq(updatedPriceFeed)
})
it("set priceFeed via non-owner causes revert transaction", async () => {
await expect(amm.connect(wallet2).setPriceFeed(l2PriceFeed.address)).to.be.revertedWith(
"PerpFiOwnableUpgrade: caller is not the owner",
)
})
it("revert if priceFeed address is zero", async () => {
await expect(amm.setPriceFeed(constants.AddressZero)).to.be.revertedWith("invalid PriceFeed address")
})
})
})
Example #20
Source File: fixtures.ts From pancake-swap-testnet with MIT License | 5 votes |
export async function v2Fixture(provider: Web3Provider, [wallet]: Wallet[]): Promise<V2Fixture> {
// deploy tokens
const tokenA = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)])
const tokenB = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)])
const WETH = await deployContract(wallet, WETH9)
const WETHPartner = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)])
// deploy V1
const factoryV1 = await deployContract(wallet, UniswapV1Factory, [])
await factoryV1.initializeFactory((await deployContract(wallet, UniswapV1Exchange, [])).address)
// deploy V2
const factoryV2 = await deployContract(wallet, PancakeFactory, [wallet.address])
// deploy routers
const router01 = await deployContract(wallet, PancakeRouter01, [factoryV2.address, WETH.address], overrides)
const router02 = await deployContract(wallet, PancakeRouter02, [factoryV2.address, WETH.address], overrides)
// event emitter for testing
const routerEventEmitter = await deployContract(wallet, RouterEventEmitter, [])
// deploy migrator
const migrator = await deployContract(wallet, PancakeMigrator, [factoryV1.address, router01.address], overrides)
// initialize V1
await factoryV1.createExchange(WETHPartner.address, overrides)
const WETHExchangeV1Address = await factoryV1.getExchange(WETHPartner.address)
const WETHExchangeV1 = new Contract(WETHExchangeV1Address, JSON.stringify(UniswapV1Exchange.abi), provider).connect(
wallet
)
// initialize V2
await factoryV2.createPair(tokenA.address, tokenB.address)
const pairAddress = await factoryV2.getPair(tokenA.address, tokenB.address)
const pair = new Contract(pairAddress, JSON.stringify(IPancakePair.abi), provider).connect(wallet)
const token0Address = await pair.token0()
const token0 = tokenA.address === token0Address ? tokenA : tokenB
const token1 = tokenA.address === token0Address ? tokenB : tokenA
await factoryV2.createPair(WETH.address, WETHPartner.address)
const WETHPairAddress = await factoryV2.getPair(WETH.address, WETHPartner.address)
const WETHPair = new Contract(WETHPairAddress, JSON.stringify(IPancakePair.abi), provider).connect(wallet)
return {
token0,
token1,
WETH,
WETHPartner,
factoryV1,
factoryV2,
router01,
router02,
router: router02, // the default router, 01 had a minor bug
routerEventEmitter,
migrator,
WETHExchangeV1,
pair,
WETHPair
}
}
Example #21
Source File: Dex.test.ts From bodhi.js with Apache License 2.0 | 4 votes |
describe('Dex', () => {
let wallet: Signer;
let dex: Contract;
before(async () => {
[wallet] = await provider.getWallets();
dex = await deployContract(wallet as any, Dex);
});
after(async () => {
provider.api.disconnect();
});
it('getLiquidityPool works', async () => {
expect(await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD)).to.be.ok;
});
it('getLiquidityPool should not works', async () => {
await expect(dex.getLiquidityPool(ADDRESS.ACA, '0x0000000000000000000001000000000000000000')).to.be.reverted;
});
it('getLiquidityTokenAddress works', async () => {
expect(await dex.getLiquidityTokenAddress(ADDRESS.ACA, ADDRESS.AUSD)).to.equal(ADDRESS.LP_ACA_AUSD);
});
it('getLiquidityTokenAddress should not works', async () => {
await expect(dex.getLiquidityTokenAddress(ADDRESS.ACA, '0x0000000000000000000001000000000000000000')).to.be
.reverted;
});
it('getSwapTargetAmount works', async () => {
expect(await dex.getSwapTargetAmount([ADDRESS.ACA, ADDRESS.AUSD], 1000)).to.be.ok;
expect(await dex.getSwapTargetAmount([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT], 1000)).to.be.ok;
});
it('getSwapTargetAmount should not works', async () => {
await expect(
dex.getSwapTargetAmount([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT, ADDRESS.RENBTC, ADDRESS.LDOT], 1000)
).to.be.revertedWith('Dex get_swap_target_amount failed');
await expect(
dex.getSwapTargetAmount([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT, ADDRESS.LDOT, ADDRESS.RENBTC], 1000)
).to.be.revertedWith('Dex get_swap_target_amount failed');
await expect(
dex.getSwapTargetAmount([ADDRESS.ACA, '0x0000000000000000000001000000000000000000'], 1000)
).to.be.revertedWith('invalid currency id');
});
it('getSwapSupplyAmount works', async () => {
expect(await dex.getSwapSupplyAmount([ADDRESS.ACA, ADDRESS.AUSD], 1000)).to.be.ok;
expect(await dex.getSwapSupplyAmount([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT], 1000)).to.be.ok;
});
it('getSwapSupplyAmount should not works', async () => {
await expect(dex.getSwapSupplyAmount([ADDRESS.ACA], 1000)).to.be.revertedWith('Dex get_swap_supply_amount failed');
await expect(
dex.getSwapSupplyAmount([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT, ADDRESS.LDOT, ADDRESS.RENBTC], 1000)
).to.be.revertedWith('Dex get_swap_supply_amount failed');
await expect(
dex.getSwapSupplyAmount([ADDRESS.ACA, '0x0000000000000000000001000000000000000000'], 1000)
).to.be.revertedWith('invalid currency id');
});
it('swapWithExactSupply works', async () => {
let pool_0 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(
await dex.swapWithExactSupply([ADDRESS.ACA, ADDRESS.AUSD], 1_000_000_000_000, 1, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
let pool_1 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(pool_1[0].sub(pool_0[0])).to.equal(1_000_000_000_000);
let pool_2 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(
await dex.swapWithExactSupply([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT], 1_000_000_000_000, 1, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
let pool_3 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(pool_3[0].sub(pool_2[0])).to.equal(1_000_000_000_000);
});
it('swapWithExactSupply should not works', async () => {
await expect(dex.swapWithExactSupply([ADDRESS.ACA], 1000, 1)).to.be.revertedWith('InvalidTradingPathLength');
await expect(
dex.swapWithExactSupply([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT, ADDRESS.LDOT, ADDRESS.RENBTC], 1000, 1)
).to.be.revertedWith('InvalidTradingPathLength');
await expect(
dex.swapWithExactSupply([ADDRESS.ACA, '0x0000000000000000000001000000000000000000'], 1000, 1)
).to.be.revertedWith('invalid currency id');
});
it('swapWithExactTarget works', async () => {
let pool_0 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(
await dex.swapWithExactTarget([ADDRESS.ACA, ADDRESS.AUSD], 1, 1_000_000_000_000, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
let pool_1 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(pool_1[1].sub(pool_0[1])).to.equal(-1);
let pool_2 = await dex.getLiquidityPool(ADDRESS.AUSD, ADDRESS.DOT);
expect(
await dex.swapWithExactTarget([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT], 1, 1_000_000_000_000, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
let pool_3 = await dex.getLiquidityPool(ADDRESS.AUSD, ADDRESS.DOT);
expect(pool_3[1].sub(pool_2[1])).to.equal(-1);
});
it('swapWithExactTarget should not works', async () => {
await expect(dex.swapWithExactTarget([ADDRESS.ACA], 1, 1000)).to.be.revertedWith('InvalidTradingPathLength');
await expect(
dex.swapWithExactTarget([ADDRESS.ACA, ADDRESS.AUSD, ADDRESS.DOT, ADDRESS.LDOT, ADDRESS.RENBTC], 1, 1000)
).to.be.revertedWith('InvalidTradingPathLength');
await expect(
dex.swapWithExactTarget([ADDRESS.ACA, '0x0000000000000000000001000000000000000000'], 1, 1000)
).to.be.revertedWith('invalid currency id');
});
it('addLiquidity and removeLiquidity works', async () => {
let pool_0 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(
await dex.swapWithExactTarget([ADDRESS.ACA, ADDRESS.AUSD], 1_000_000_000_000, 1_000_000_000_000, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
let pool_1 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(pool_1[1].sub(pool_0[1])).to.equal(-1_000_000_000_000);
expect(
await dex.addLiquidity(ADDRESS.ACA, ADDRESS.AUSD, 1_000_000_000_000, 1_000_000_000_000, 0, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
let pool_2 = await dex.getLiquidityPool(ADDRESS.ACA, ADDRESS.AUSD);
expect(pool_2[1].sub(pool_1[1])).to.equal(1_000_000_000_000);
expect(
await dex.removeLiquidity(ADDRESS.ACA, ADDRESS.AUSD, 100_000_000_000, 0, 0, {
value: ethers.utils.parseEther('1'),
gasLimit: 2_000_000
})
).to.be.ok;
});
it('addLiquidity should not works', async () => {
await expect(dex.addLiquidity(ADDRESS.ACA, '0x0000000000000000000001000000000000000000', 1, 1000, 0)).to.be
.reverted;
});
it('removeLiquidity should not works', async () => {
await expect(dex.addLiquidity(ADDRESS.ACA, '0x0000000000000000000001000000000000000000', 1, 1000, 0)).to.be
.reverted;
});
});
Example #22
Source File: VvsERC20.spec.ts From vvs-swap-core with GNU General Public License v3.0 | 4 votes |
describe("VVSERC20", () => {
const provider = new MockProvider({
ganacheOptions: {
hardfork: "istanbul",
mnemonic: "horn horn horn horn horn horn horn horn horn horn horn horn",
gasLimit: 9999999
}
});
const [wallet, other] = provider.getWallets();
let token: Contract;
beforeEach(async () => {
token = await deployContract(wallet, ERC20, [TOTAL_SUPPLY]);
});
it("name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, PERMIT_TYPEHASH", async () => {
const name = await token.name();
expect(name).to.eq("VVS Finance LPs");
expect(await token.symbol()).to.eq("VVS-LP");
expect(await token.decimals()).to.eq(18);
expect(await token.totalSupply()).to.eq(TOTAL_SUPPLY);
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY);
expect(await token.DOMAIN_SEPARATOR()).to.eq(
keccak256(
defaultAbiCoder.encode(
["bytes32", "bytes32", "bytes32", "uint256", "address"],
[
keccak256(
toUtf8Bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
),
keccak256(toUtf8Bytes(name)),
keccak256(toUtf8Bytes("1")),
1,
token.address
]
)
)
);
expect(await token.PERMIT_TYPEHASH()).to.eq(
keccak256(toUtf8Bytes("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"))
);
});
it("approve", async () => {
await expect(token.approve(other.address, TEST_AMOUNT))
.to.emit(token, "Approval")
.withArgs(wallet.address, other.address, TEST_AMOUNT);
expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT);
});
it("transfer", async () => {
await expect(token.transfer(other.address, TEST_AMOUNT))
.to.emit(token, "Transfer")
.withArgs(wallet.address, other.address, TEST_AMOUNT);
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT));
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT);
});
it("transfer:fail", async () => {
await expect(token.transfer(other.address, TOTAL_SUPPLY.add(1))).to.be.reverted; // ds-math-sub-underflow
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.reverted; // ds-math-sub-underflow
});
it("transferFrom", async () => {
await token.approve(other.address, TEST_AMOUNT);
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
.to.emit(token, "Transfer")
.withArgs(wallet.address, other.address, TEST_AMOUNT);
expect(await token.allowance(wallet.address, other.address)).to.eq(0);
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT));
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT);
});
it("transferFrom:max", async () => {
await token.approve(other.address, MaxUint256);
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
.to.emit(token, "Transfer")
.withArgs(wallet.address, other.address, TEST_AMOUNT);
expect(await token.allowance(wallet.address, other.address)).to.eq(MaxUint256);
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT));
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT);
});
it("permit", async () => {
const nonce = await token.nonces(wallet.address);
const deadline = MaxUint256;
const digest = await getApprovalDigest(
token,
{ owner: wallet.address, spender: other.address, value: TEST_AMOUNT },
nonce,
deadline
);
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), "hex"), Buffer.from(wallet.privateKey.slice(2), "hex"));
await expect(token.permit(wallet.address, other.address, TEST_AMOUNT, deadline, v, hexlify(r), hexlify(s)))
.to.emit(token, "Approval")
.withArgs(wallet.address, other.address, TEST_AMOUNT);
expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT);
expect(await token.nonces(wallet.address)).to.eq(BigNumber.from(1));
});
});
Example #23
Source File: StakingRewards.spec.ts From staking-factory with MIT License | 4 votes |
describe('StakingRewards', () => {
const provider = new MockProvider({
ganacheOptions: {
hardfork: 'istanbul',
mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
gasLimit: 9999999,
},
})
const [wallet, staker, secondStaker] = provider.getWallets()
const loadFixture = createFixtureLoader([wallet], provider)
let stakingRewards: Contract
let rewardsToken: Contract
let stakingToken: Contract
beforeEach(async () => {
const fixture = await loadFixture(stakingRewardsFixture)
stakingRewards = fixture.stakingRewards
rewardsToken = fixture.rewardsToken
stakingToken = fixture.stakingToken
})
it('deploy cost', async () => {
const stakingRewards = await deployContract(wallet, StakingRewards, [
wallet.address,
rewardsToken.address,
stakingToken.address,
])
const receipt = await provider.getTransactionReceipt(stakingRewards.deployTransaction.hash)
expect(receipt.gasUsed).to.eq('1418436')
})
it('rewardsDuration', async () => {
const rewardsDuration = await stakingRewards.rewardsDuration()
expect(rewardsDuration).to.be.eq(REWARDS_DURATION)
})
const reward = expandTo18Decimals(100)
async function start(reward: BigNumber): Promise<{ startTime: BigNumber; endTime: BigNumber }> {
// send reward to the contract
await rewardsToken.transfer(stakingRewards.address, reward)
// must be called by rewardsDistribution
await stakingRewards.notifyRewardAmount(reward)
const startTime: BigNumber = await stakingRewards.lastUpdateTime()
const endTime: BigNumber = await stakingRewards.periodFinish()
expect(endTime).to.be.eq(startTime.add(REWARDS_DURATION))
return { startTime, endTime }
}
it('notifyRewardAmount: full', async () => {
// stake with staker
const stake = expandTo18Decimals(2)
await stakingToken.transfer(staker.address, stake)
await stakingToken.connect(staker).approve(stakingRewards.address, stake)
await stakingRewards.connect(staker).stake(stake)
const { endTime } = await start(reward)
// fast-forward past the reward window
await mineBlock(provider, endTime.add(1).toNumber())
// unstake
await stakingRewards.connect(staker).exit()
const stakeEndTime: BigNumber = await stakingRewards.lastUpdateTime()
expect(stakeEndTime).to.be.eq(endTime)
const rewardAmount = await rewardsToken.balanceOf(staker.address)
expect(reward.sub(rewardAmount).lte(reward.div(10000))).to.be.true // ensure result is within .01%
expect(rewardAmount).to.be.eq(reward.div(REWARDS_DURATION).mul(REWARDS_DURATION))
})
it('stakeWithPermit', async () => {
// stake with staker
const stake = expandTo18Decimals(2)
await stakingToken.transfer(staker.address, stake)
// get permit
const nonce = await stakingToken.nonces(staker.address)
const deadline = constants.MaxUint256
const digest = await getApprovalDigest(
stakingToken,
{ owner: staker.address, spender: stakingRewards.address, value: stake },
nonce,
deadline
)
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(staker.privateKey.slice(2), 'hex'))
await stakingRewards.connect(staker).stakeWithPermit(stake, deadline, v, r, s)
const { endTime } = await start(reward)
// fast-forward past the reward window
await mineBlock(provider, endTime.add(1).toNumber())
// unstake
await stakingRewards.connect(staker).exit()
const stakeEndTime: BigNumber = await stakingRewards.lastUpdateTime()
expect(stakeEndTime).to.be.eq(endTime)
const rewardAmount = await rewardsToken.balanceOf(staker.address)
expect(reward.sub(rewardAmount).lte(reward.div(10000))).to.be.true // ensure result is within .01%
expect(rewardAmount).to.be.eq(reward.div(REWARDS_DURATION).mul(REWARDS_DURATION))
})
it('notifyRewardAmount: ~half', async () => {
const { startTime, endTime } = await start(reward)
// fast-forward ~halfway through the reward window
await mineBlock(provider, startTime.add(endTime.sub(startTime).div(2)).toNumber())
// stake with staker
const stake = expandTo18Decimals(2)
await stakingToken.transfer(staker.address, stake)
await stakingToken.connect(staker).approve(stakingRewards.address, stake)
await stakingRewards.connect(staker).stake(stake)
const stakeStartTime: BigNumber = await stakingRewards.lastUpdateTime()
// fast-forward past the reward window
await mineBlock(provider, endTime.add(1).toNumber())
// unstake
await stakingRewards.connect(staker).exit()
const stakeEndTime: BigNumber = await stakingRewards.lastUpdateTime()
expect(stakeEndTime).to.be.eq(endTime)
const rewardAmount = await rewardsToken.balanceOf(staker.address)
expect(reward.div(2).sub(rewardAmount).lte(reward.div(2).div(10000))).to.be.true // ensure result is within .01%
expect(rewardAmount).to.be.eq(reward.div(REWARDS_DURATION).mul(endTime.sub(stakeStartTime)))
}).retries(2)
it('notifyRewardAmount: two stakers', async () => {
// stake with first staker
const stake = expandTo18Decimals(2)
await stakingToken.transfer(staker.address, stake)
await stakingToken.connect(staker).approve(stakingRewards.address, stake)
await stakingRewards.connect(staker).stake(stake)
const { startTime, endTime } = await start(reward)
// fast-forward ~halfway through the reward window
await mineBlock(provider, startTime.add(endTime.sub(startTime).div(2)).toNumber())
// stake with second staker
await stakingToken.transfer(secondStaker.address, stake)
await stakingToken.connect(secondStaker).approve(stakingRewards.address, stake)
await stakingRewards.connect(secondStaker).stake(stake)
// fast-forward past the reward window
await mineBlock(provider, endTime.add(1).toNumber())
// unstake
await stakingRewards.connect(staker).exit()
const stakeEndTime: BigNumber = await stakingRewards.lastUpdateTime()
expect(stakeEndTime).to.be.eq(endTime)
await stakingRewards.connect(secondStaker).exit()
const rewardAmount = await rewardsToken.balanceOf(staker.address)
const secondRewardAmount = await rewardsToken.balanceOf(secondStaker.address)
const totalReward = rewardAmount.add(secondRewardAmount)
// ensure results are within .01%
expect(reward.sub(totalReward).lte(reward.div(10000))).to.be.true
expect(totalReward.mul(3).div(4).sub(rewardAmount).lte(totalReward.mul(3).div(4).div(10000)))
expect(totalReward.div(4).sub(secondRewardAmount).lte(totalReward.div(4).div(10000)))
})
})
Example #24
Source File: ExampleSwapToPrice.spec.ts From pancake-swap-testnet with MIT License | 4 votes |
describe('ExampleSwapToPrice', () => {
const provider = new MockProvider({
hardfork: 'istanbul',
mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
gasLimit: 9999999
})
const [wallet] = provider.getWallets()
const loadFixture = createFixtureLoader(provider, [wallet])
let token0: Contract
let token1: Contract
let pair: Contract
let swapToPriceExample: Contract
let router: Contract
beforeEach(async function() {
const fixture = await loadFixture(v2Fixture)
token0 = fixture.token0
token1 = fixture.token1
pair = fixture.pair
router = fixture.router
swapToPriceExample = await deployContract(
wallet,
ExampleSwapToPrice,
[fixture.factoryV2.address, fixture.router.address],
overrides
)
})
beforeEach('set up price differential of 1:100', async () => {
await token0.transfer(pair.address, expandTo18Decimals(10))
await token1.transfer(pair.address, expandTo18Decimals(1000))
await pair.sync(overrides)
})
beforeEach('approve the swap contract to spend any amount of both tokens', async () => {
await token0.approve(swapToPriceExample.address, MaxUint256)
await token1.approve(swapToPriceExample.address, MaxUint256)
})
it('correct router address', async () => {
expect(await swapToPriceExample.router()).to.eq(router.address)
})
describe('#swapToPrice', () => {
it('requires non-zero true price inputs', async () => {
await expect(
swapToPriceExample.swapToPrice(
token0.address,
token1.address,
0,
0,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256
)
).to.be.revertedWith('ExampleSwapToPrice: ZERO_PRICE')
await expect(
swapToPriceExample.swapToPrice(
token0.address,
token1.address,
10,
0,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256
)
).to.be.revertedWith('ExampleSwapToPrice: ZERO_PRICE')
await expect(
swapToPriceExample.swapToPrice(
token0.address,
token1.address,
0,
10,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256
)
).to.be.revertedWith('ExampleSwapToPrice: ZERO_PRICE')
})
it('requires non-zero max spend', async () => {
await expect(
swapToPriceExample.swapToPrice(token0.address, token1.address, 1, 100, 0, 0, wallet.address, MaxUint256)
).to.be.revertedWith('ExampleSwapToPrice: ZERO_SPEND')
})
it('moves the price to 1:90', async () => {
await expect(
swapToPriceExample.swapToPrice(
token0.address,
token1.address,
1,
90,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256,
overrides
)
)
// (1e19 + 526682316179835569) : (1e21 - 49890467170695440744) ~= 1:90
.to.emit(token0, 'Transfer')
.withArgs(wallet.address, swapToPriceExample.address, '526682316179835569')
.to.emit(token0, 'Approval')
.withArgs(swapToPriceExample.address, router.address, '526682316179835569')
.to.emit(token0, 'Transfer')
.withArgs(swapToPriceExample.address, pair.address, '526682316179835569')
.to.emit(token1, 'Transfer')
.withArgs(pair.address, wallet.address, '49890467170695440744')
})
it('moves the price to 1:110', async () => {
await expect(
swapToPriceExample.swapToPrice(
token0.address,
token1.address,
1,
110,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256,
overrides
)
)
// (1e21 + 47376582963642643588) : (1e19 - 451039908682851138) ~= 1:110
.to.emit(token1, 'Transfer')
.withArgs(wallet.address, swapToPriceExample.address, '47376582963642643588')
.to.emit(token1, 'Approval')
.withArgs(swapToPriceExample.address, router.address, '47376582963642643588')
.to.emit(token1, 'Transfer')
.withArgs(swapToPriceExample.address, pair.address, '47376582963642643588')
.to.emit(token0, 'Transfer')
.withArgs(pair.address, wallet.address, '451039908682851138')
})
it('reverse token order', async () => {
await expect(
swapToPriceExample.swapToPrice(
token1.address,
token0.address,
110,
1,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256,
overrides
)
)
// (1e21 + 47376582963642643588) : (1e19 - 451039908682851138) ~= 1:110
.to.emit(token1, 'Transfer')
.withArgs(wallet.address, swapToPriceExample.address, '47376582963642643588')
.to.emit(token1, 'Approval')
.withArgs(swapToPriceExample.address, router.address, '47376582963642643588')
.to.emit(token1, 'Transfer')
.withArgs(swapToPriceExample.address, pair.address, '47376582963642643588')
.to.emit(token0, 'Transfer')
.withArgs(pair.address, wallet.address, '451039908682851138')
})
it('swap gas cost', async () => {
const tx = await swapToPriceExample.swapToPrice(
token0.address,
token1.address,
1,
110,
MaxUint256,
MaxUint256,
wallet.address,
MaxUint256,
overrides
)
const receipt = await tx.wait()
expect(receipt.gasUsed).to.eq('122329')
}).retries(2) // gas test is inconsistent
})
})
Example #25
Source File: ExampleSlidingWindowOracle.spec.ts From pancake-swap-testnet with MIT License | 4 votes |
describe('ExampleSlidingWindowOracle', () => {
const provider = new MockProvider({
hardfork: 'istanbul',
mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
gasLimit: 9999999
})
const [wallet] = provider.getWallets()
const loadFixture = createFixtureLoader(provider, [wallet])
let token0: Contract
let token1: Contract
let pair: Contract
let weth: Contract
let factory: Contract
async function addLiquidity(amount0: BigNumber = defaultToken0Amount, amount1: BigNumber = defaultToken1Amount) {
if (!amount0.isZero()) await token0.transfer(pair.address, amount0)
if (!amount1.isZero()) await token1.transfer(pair.address, amount1)
await pair.sync()
}
const defaultWindowSize = 86400 // 24 hours
const defaultGranularity = 24 // 1 hour each
function observationIndexOf(
timestamp: number,
windowSize: number = defaultWindowSize,
granularity: number = defaultGranularity
): number {
const periodSize = Math.floor(windowSize / granularity)
const epochPeriod = Math.floor(timestamp / periodSize)
return epochPeriod % granularity
}
function deployOracle(windowSize: number, granularity: number) {
return deployContract(wallet, ExampleSlidingWindowOracle, [factory.address, windowSize, granularity], overrides)
}
beforeEach('deploy fixture', async function() {
const fixture = await loadFixture(v2Fixture)
token0 = fixture.token0
token1 = fixture.token1
pair = fixture.pair
weth = fixture.WETH
factory = fixture.factoryV2
})
// 1/1/2020 @ 12:00 am UTC
// cannot be 0 because that instructs ganache to set it to current timestamp
// cannot be 86400 because then timestamp 0 is a valid historical observation
const startTime = 1577836800
// must come before adding liquidity to pairs for correct cumulative price computations
// cannot use 0 because that resets to current timestamp
beforeEach(`set start time to ${startTime}`, () => mineBlock(provider, startTime))
it('requires granularity to be greater than 0', async () => {
await expect(deployOracle(defaultWindowSize, 0)).to.be.revertedWith('SlidingWindowOracle: GRANULARITY')
})
it('requires windowSize to be evenly divisible by granularity', async () => {
await expect(deployOracle(defaultWindowSize - 1, defaultGranularity)).to.be.revertedWith(
'SlidingWindowOracle: WINDOW_NOT_EVENLY_DIVISIBLE'
)
})
it('computes the periodSize correctly', async () => {
const oracle = await deployOracle(defaultWindowSize, defaultGranularity)
expect(await oracle.periodSize()).to.eq(3600)
const oracleOther = await deployOracle(defaultWindowSize * 2, defaultGranularity / 2)
expect(await oracleOther.periodSize()).to.eq(3600 * 4)
})
describe('#observationIndexOf', () => {
it('works for examples', async () => {
const oracle = await deployOracle(defaultWindowSize, defaultGranularity)
expect(await oracle.observationIndexOf(0)).to.eq(0)
expect(await oracle.observationIndexOf(3599)).to.eq(0)
expect(await oracle.observationIndexOf(3600)).to.eq(1)
expect(await oracle.observationIndexOf(4800)).to.eq(1)
expect(await oracle.observationIndexOf(7199)).to.eq(1)
expect(await oracle.observationIndexOf(7200)).to.eq(2)
expect(await oracle.observationIndexOf(86399)).to.eq(23)
expect(await oracle.observationIndexOf(86400)).to.eq(0)
expect(await oracle.observationIndexOf(90000)).to.eq(1)
})
it('overflow safe', async () => {
const oracle = await deployOracle(25500, 255) // 100 period size
expect(await oracle.observationIndexOf(0)).to.eq(0)
expect(await oracle.observationIndexOf(99)).to.eq(0)
expect(await oracle.observationIndexOf(100)).to.eq(1)
expect(await oracle.observationIndexOf(199)).to.eq(1)
expect(await oracle.observationIndexOf(25499)).to.eq(254) // 255th element
expect(await oracle.observationIndexOf(25500)).to.eq(0)
})
it('matches offline computation', async () => {
const oracle = await deployOracle(defaultWindowSize, defaultGranularity)
for (let timestamp of [0, 5000, 1000, 25000, 86399, 86400, 86401]) {
expect(await oracle.observationIndexOf(timestamp)).to.eq(observationIndexOf(timestamp))
}
})
})
describe('#update', () => {
let slidingWindowOracle: Contract
beforeEach(
'deploy oracle',
async () => (slidingWindowOracle = await deployOracle(defaultWindowSize, defaultGranularity))
)
beforeEach('add default liquidity', () => addLiquidity())
it('succeeds', async () => {
await slidingWindowOracle.update(token0.address, token1.address, overrides)
})
it('sets the appropriate epoch slot', async () => {
const blockTimestamp = (await pair.getReserves())[2]
expect(blockTimestamp).to.eq(startTime)
await slidingWindowOracle.update(token0.address, token1.address, overrides)
expect(await slidingWindowOracle.pairObservations(pair.address, observationIndexOf(blockTimestamp))).to.deep.eq([
bigNumberify(blockTimestamp),
await pair.price0CumulativeLast(),
await pair.price1CumulativeLast()
])
}).retries(2) // we may have slight differences between pair blockTimestamp and the expected timestamp
// because the previous block timestamp may differ from the current block timestamp by 1 second
it('gas for first update (allocates empty array)', async () => {
const tx = await slidingWindowOracle.update(token0.address, token1.address, overrides)
const receipt = await tx.wait()
expect(receipt.gasUsed).to.eq('116816')
}).retries(2) // gas test inconsistent
it('gas for second update in the same period (skips)', async () => {
await slidingWindowOracle.update(token0.address, token1.address, overrides)
const tx = await slidingWindowOracle.update(token0.address, token1.address, overrides)
const receipt = await tx.wait()
expect(receipt.gasUsed).to.eq('25574')
}).retries(2) // gas test inconsistent
it('gas for second update different period (no allocate, no skip)', async () => {
await slidingWindowOracle.update(token0.address, token1.address, overrides)
await mineBlock(provider, startTime + 3600)
const tx = await slidingWindowOracle.update(token0.address, token1.address, overrides)
const receipt = await tx.wait()
expect(receipt.gasUsed).to.eq('94542')
}).retries(2) // gas test inconsistent
it('second update in one timeslot does not overwrite', async () => {
await slidingWindowOracle.update(token0.address, token1.address, overrides)
const before = await slidingWindowOracle.pairObservations(pair.address, observationIndexOf(0))
// first hour still
await mineBlock(provider, startTime + 1800)
await slidingWindowOracle.update(token0.address, token1.address, overrides)
const after = await slidingWindowOracle.pairObservations(pair.address, observationIndexOf(1800))
expect(observationIndexOf(1800)).to.eq(observationIndexOf(0))
expect(before).to.deep.eq(after)
})
it('fails for invalid pair', async () => {
await expect(slidingWindowOracle.update(weth.address, token1.address)).to.be.reverted
})
})
describe('#consult', () => {
let slidingWindowOracle: Contract
beforeEach(
'deploy oracle',
async () => (slidingWindowOracle = await deployOracle(defaultWindowSize, defaultGranularity))
)
// must come after setting time to 0 for correct cumulative price computations in the pair
beforeEach('add default liquidity', () => addLiquidity())
it('fails if previous bucket not set', async () => {
await slidingWindowOracle.update(token0.address, token1.address, overrides)
await expect(slidingWindowOracle.consult(token0.address, 0, token1.address)).to.be.revertedWith(
'SlidingWindowOracle: MISSING_HISTORICAL_OBSERVATION'
)
})
it('fails for invalid pair', async () => {
await expect(slidingWindowOracle.consult(weth.address, 0, token1.address)).to.be.reverted
})
describe('happy path', () => {
let blockTimestamp: number
let previousBlockTimestamp: number
let previousCumulativePrices: any
beforeEach('add some prices', async () => {
previousBlockTimestamp = (await pair.getReserves())[2]
previousCumulativePrices = [await pair.price0CumulativeLast(), await pair.price1CumulativeLast()]
await slidingWindowOracle.update(token0.address, token1.address, overrides)
blockTimestamp = previousBlockTimestamp + 23 * 3600
await mineBlock(provider, blockTimestamp)
await slidingWindowOracle.update(token0.address, token1.address, overrides)
})
it('has cumulative price in previous bucket', async () => {
expect(
await slidingWindowOracle.pairObservations(pair.address, observationIndexOf(previousBlockTimestamp))
).to.deep.eq([bigNumberify(previousBlockTimestamp), previousCumulativePrices[0], previousCumulativePrices[1]])
}).retries(5) // test flaky because timestamps aren't mocked
it('has cumulative price in current bucket', async () => {
const timeElapsed = blockTimestamp - previousBlockTimestamp
const prices = encodePrice(defaultToken0Amount, defaultToken1Amount)
expect(
await slidingWindowOracle.pairObservations(pair.address, observationIndexOf(blockTimestamp))
).to.deep.eq([bigNumberify(blockTimestamp), prices[0].mul(timeElapsed), prices[1].mul(timeElapsed)])
}).retries(5) // test flaky because timestamps aren't mocked
it('provides the current ratio in consult token0', async () => {
expect(await slidingWindowOracle.consult(token0.address, 100, token1.address)).to.eq(200)
})
it('provides the current ratio in consult token1', async () => {
expect(await slidingWindowOracle.consult(token1.address, 100, token0.address)).to.eq(50)
})
})
describe('price changes over period', () => {
const hour = 3600
beforeEach('add some prices', async () => {
// starting price of 1:2, or token0 = 2token1, token1 = 0.5token0
await slidingWindowOracle.update(token0.address, token1.address, overrides) // hour 0, 1:2
// change the price at hour 3 to 1:1 and immediately update
await mineBlock(provider, startTime + 3 * hour)
await addLiquidity(defaultToken0Amount, bigNumberify(0))
await slidingWindowOracle.update(token0.address, token1.address, overrides)
// change the ratios at hour 6:00 to 2:1, don't update right away
await mineBlock(provider, startTime + 6 * hour)
await token0.transfer(pair.address, defaultToken0Amount.mul(2))
await pair.sync()
// update at hour 9:00 (price has been 2:1 for 3 hours, invokes counterfactual)
await mineBlock(provider, startTime + 9 * hour)
await slidingWindowOracle.update(token0.address, token1.address, overrides)
// move to hour 23:00 so we can check prices
await mineBlock(provider, startTime + 23 * hour)
})
it('provides the correct ratio in consult token0', async () => {
// at hour 23, price of token 0 spent 3 hours at 2, 3 hours at 1, 17 hours at 0.5 so price should
// be less than 1
expect(await slidingWindowOracle.consult(token0.address, 100, token1.address)).to.eq(76)
})
it('provides the correct ratio in consult token1', async () => {
// price should be greater than 1
expect(await slidingWindowOracle.consult(token1.address, 100, token0.address)).to.eq(167)
})
// price has been 2:1 all of 23 hours
describe('hour 32', () => {
beforeEach('set hour 32', () => mineBlock(provider, startTime + 32 * hour))
it('provides the correct ratio in consult token0', async () => {
// at hour 23, price of token 0 spent 3 hours at 2, 3 hours at 1, 17 hours at 0.5 so price should
// be less than 1
expect(await slidingWindowOracle.consult(token0.address, 100, token1.address)).to.eq(50)
})
it('provides the correct ratio in consult token1', async () => {
// price should be greater than 1
expect(await slidingWindowOracle.consult(token1.address, 100, token0.address)).to.eq(200)
})
})
})
})
})
Example #26
Source File: ExampleFlashSwap.spec.ts From pancake-swap-testnet with MIT License | 4 votes |
describe('ExampleFlashSwap', () => {
const provider = new MockProvider({
hardfork: 'istanbul',
mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
gasLimit: 9999999
})
const [wallet] = provider.getWallets()
const loadFixture = createFixtureLoader(provider, [wallet])
let WETH: Contract
let WETHPartner: Contract
let WETHExchangeV1: Contract
let WETHPair: Contract
let flashSwapExample: Contract
beforeEach(async function() {
const fixture = await loadFixture(v2Fixture)
WETH = fixture.WETH
WETHPartner = fixture.WETHPartner
WETHExchangeV1 = fixture.WETHExchangeV1
WETHPair = fixture.WETHPair
flashSwapExample = await deployContract(
wallet,
ExampleFlashSwap,
[fixture.factoryV2.address, fixture.factoryV1.address, fixture.router.address],
overrides
)
})
it('uniswapV2Call:0', async () => {
// add liquidity to V1 at a rate of 1 ETH / 200 X
const WETHPartnerAmountV1 = expandTo18Decimals(2000)
const ETHAmountV1 = expandTo18Decimals(10)
await WETHPartner.approve(WETHExchangeV1.address, WETHPartnerAmountV1)
await WETHExchangeV1.addLiquidity(bigNumberify(1), WETHPartnerAmountV1, MaxUint256, {
...overrides,
value: ETHAmountV1
})
// add liquidity to V2 at a rate of 1 ETH / 100 X
const WETHPartnerAmountV2 = expandTo18Decimals(1000)
const ETHAmountV2 = expandTo18Decimals(10)
await WETHPartner.transfer(WETHPair.address, WETHPartnerAmountV2)
await WETH.deposit({ value: ETHAmountV2 })
await WETH.transfer(WETHPair.address, ETHAmountV2)
await WETHPair.mint(wallet.address, overrides)
const balanceBefore = await WETHPartner.balanceOf(wallet.address)
// now, execute arbitrage via uniswapV2Call:
// receive 1 ETH from V2, get as much X from V1 as we can, repay V2 with minimum X, keep the rest!
const arbitrageAmount = expandTo18Decimals(1)
// instead of being 'hard-coded', the above value could be calculated optimally off-chain. this would be
// better, but it'd be better yet to calculate the amount at runtime, on-chain. unfortunately, this requires a
// swap-to-price calculation, which is a little tricky, and out of scope for the moment
const WETHPairToken0 = await WETHPair.token0()
const amount0 = WETHPairToken0 === WETHPartner.address ? bigNumberify(0) : arbitrageAmount
const amount1 = WETHPairToken0 === WETHPartner.address ? arbitrageAmount : bigNumberify(0)
await WETHPair.swap(
amount0,
amount1,
flashSwapExample.address,
defaultAbiCoder.encode(['uint'], [bigNumberify(1)]),
overrides
)
const balanceAfter = await WETHPartner.balanceOf(wallet.address)
const profit = balanceAfter.sub(balanceBefore).div(expandTo18Decimals(1))
const reservesV1 = [
await WETHPartner.balanceOf(WETHExchangeV1.address),
await provider.getBalance(WETHExchangeV1.address)
]
const priceV1 = reservesV1[0].div(reservesV1[1])
const reservesV2 = (await WETHPair.getReserves()).slice(0, 2)
const priceV2 =
WETHPairToken0 === WETHPartner.address ? reservesV2[0].div(reservesV2[1]) : reservesV2[1].div(reservesV2[0])
expect(profit.toString()).to.eq('69') // our profit is ~69 tokens
expect(priceV1.toString()).to.eq('165') // we pushed the v1 price down to ~165
expect(priceV2.toString()).to.eq('123') // we pushed the v2 price up to ~123
})
it('uniswapV2Call:1', async () => {
// add liquidity to V1 at a rate of 1 ETH / 100 X
const WETHPartnerAmountV1 = expandTo18Decimals(1000)
const ETHAmountV1 = expandTo18Decimals(10)
await WETHPartner.approve(WETHExchangeV1.address, WETHPartnerAmountV1)
await WETHExchangeV1.addLiquidity(bigNumberify(1), WETHPartnerAmountV1, MaxUint256, {
...overrides,
value: ETHAmountV1
})
// add liquidity to V2 at a rate of 1 ETH / 200 X
const WETHPartnerAmountV2 = expandTo18Decimals(2000)
const ETHAmountV2 = expandTo18Decimals(10)
await WETHPartner.transfer(WETHPair.address, WETHPartnerAmountV2)
await WETH.deposit({ value: ETHAmountV2 })
await WETH.transfer(WETHPair.address, ETHAmountV2)
await WETHPair.mint(wallet.address, overrides)
const balanceBefore = await provider.getBalance(wallet.address)
// now, execute arbitrage via uniswapV2Call:
// receive 200 X from V2, get as much ETH from V1 as we can, repay V2 with minimum ETH, keep the rest!
const arbitrageAmount = expandTo18Decimals(200)
// instead of being 'hard-coded', the above value could be calculated optimally off-chain. this would be
// better, but it'd be better yet to calculate the amount at runtime, on-chain. unfortunately, this requires a
// swap-to-price calculation, which is a little tricky, and out of scope for the moment
const WETHPairToken0 = await WETHPair.token0()
const amount0 = WETHPairToken0 === WETHPartner.address ? arbitrageAmount : bigNumberify(0)
const amount1 = WETHPairToken0 === WETHPartner.address ? bigNumberify(0) : arbitrageAmount
await WETHPair.swap(
amount0,
amount1,
flashSwapExample.address,
defaultAbiCoder.encode(['uint'], [bigNumberify(1)]),
overrides
)
const balanceAfter = await provider.getBalance(wallet.address)
const profit = balanceAfter.sub(balanceBefore)
const reservesV1 = [
await WETHPartner.balanceOf(WETHExchangeV1.address),
await provider.getBalance(WETHExchangeV1.address)
]
const priceV1 = reservesV1[0].div(reservesV1[1])
const reservesV2 = (await WETHPair.getReserves()).slice(0, 2)
const priceV2 =
WETHPairToken0 === WETHPartner.address ? reservesV2[0].div(reservesV2[1]) : reservesV2[1].div(reservesV2[0])
expect(formatEther(profit)).to.eq('0.548043441089763649') // our profit is ~.5 ETH
expect(priceV1.toString()).to.eq('143') // we pushed the v1 price up to ~143
expect(priceV2.toString()).to.eq('161') // we pushed the v2 price down to ~161
})
})
Example #27
Source File: PancakeERC20.spec.ts From pancake-swap-testnet with MIT License | 4 votes |
describe('PancakeERC20', () => {
const provider = new MockProvider({
hardfork: 'istanbul',
mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
gasLimit: 9999999
})
const [wallet, other] = provider.getWallets()
let token: Contract
beforeEach(async () => {
token = await deployContract(wallet, ERC20, [TOTAL_SUPPLY])
})
it('name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, PERMIT_TYPEHASH', async () => {
const name = await token.name()
expect(name).to.eq('Pancake LPs')
expect(await token.symbol()).to.eq('Cake-LP')
expect(await token.decimals()).to.eq(18)
expect(await token.totalSupply()).to.eq(TOTAL_SUPPLY)
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY)
expect(await token.DOMAIN_SEPARATOR()).to.eq(
keccak256(
defaultAbiCoder.encode(
['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'],
[
keccak256(
toUtf8Bytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')
),
keccak256(toUtf8Bytes(name)),
keccak256(toUtf8Bytes('1')),
1,
token.address
]
)
)
)
expect(await token.PERMIT_TYPEHASH()).to.eq(
keccak256(toUtf8Bytes('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'))
)
})
it('approve', async () => {
await expect(token.approve(other.address, TEST_AMOUNT))
.to.emit(token, 'Approval')
.withArgs(wallet.address, other.address, TEST_AMOUNT)
expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT)
})
it('transfer', async () => {
await expect(token.transfer(other.address, TEST_AMOUNT))
.to.emit(token, 'Transfer')
.withArgs(wallet.address, other.address, TEST_AMOUNT)
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT))
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
})
it('transfer:fail', async () => {
await expect(token.transfer(other.address, TOTAL_SUPPLY.add(1))).to.be.reverted // ds-math-sub-underflow
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.reverted // ds-math-sub-underflow
})
it('transferFrom', async () => {
await token.approve(other.address, TEST_AMOUNT)
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
.to.emit(token, 'Transfer')
.withArgs(wallet.address, other.address, TEST_AMOUNT)
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT))
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
})
it('transferFrom:max', async () => {
await token.approve(other.address, MaxUint256)
await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT))
.to.emit(token, 'Transfer')
.withArgs(wallet.address, other.address, TEST_AMOUNT)
expect(await token.allowance(wallet.address, other.address)).to.eq(MaxUint256)
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT))
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
})
it('permit', async () => {
const nonce = await token.nonces(wallet.address)
const deadline = MaxUint256
const digest = await getApprovalDigest(
token,
{ owner: wallet.address, spender: other.address, value: TEST_AMOUNT },
nonce,
deadline
)
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(wallet.privateKey.slice(2), 'hex'))
await expect(token.permit(wallet.address, other.address, TEST_AMOUNT, deadline, v, hexlify(r), hexlify(s)))
.to.emit(token, 'Approval')
.withArgs(wallet.address, other.address, TEST_AMOUNT)
expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT)
expect(await token.nonces(wallet.address)).to.eq(bigNumberify(1))
})
})
Example #28
Source File: Scheduler.test.ts From bodhi.js with Apache License 2.0 | 4 votes |
describe('Schedule', () => {
let wallet: Signer;
let walletTo: Signer;
let subscriber: Signer;
let schedule: Contract;
before(async () => {
[wallet, walletTo, subscriber] = await provider.getWallets();
schedule = await new ethers.Contract(ADDRESS.Schedule, SCHEDULE_CALL_ABI, wallet as any);
});
after(async () => {
provider.api.disconnect();
});
it('ScheduleCall works', async () => {
const target_block_number = Number(await provider.api.query.system.number()) + 4;
const erc20 = new ethers.Contract(ADDRESS.DOT, ERC20_ABI, walletTo as any);
const tx = await erc20.populateTransaction.transfer(walletTo.getAddress(), 1_000_000);
// console.log(tx, ethers.utils.hexlify(tx.data as string));
await schedule.scheduleCall(ADDRESS.DOT, 0, 300000, 10000, 1, ethers.utils.hexlify(tx.data as string));
let current_block_number = Number(await provider.api.query.system.number());
let balance = await erc20.balanceOf(await walletTo.getAddress());
while (current_block_number < target_block_number) {
await next_block(current_block_number);
current_block_number = Number(await provider.api.query.system.number());
}
let new_balance = await erc20.balanceOf(await walletTo.getAddress());
expect(new_balance.toString()).to.equal(balance.add(1_000_000).toString());
});
it('CancelCall works', async () => {
const erc20 = new ethers.Contract(ADDRESS.DOT, ERC20_ABI, walletTo as any);
const tx = await erc20.populateTransaction.transfer(walletTo.getAddress(), 1_000_000);
// console.log(tx, ethers.utils.hexlify(tx.data as string));
let iface = new ethers.utils.Interface(SCHEDULE_CALL_ABI);
let current_block_number = Number(await provider.api.query.system.number());
await schedule.scheduleCall(ADDRESS.DOT, 0, 300000, 10000, 2, ethers.utils.hexlify(tx.data as string));
let block_hash = await provider.api.rpc.chain.getBlockHash(current_block_number + 1);
const data = await provider.api.derive.tx.events(block_hash);
let event = data.events.filter((item) => provider.api.events.evm.Executed.is(item.event));
expect(event.length).above(0);
let decode_log = iface.parseLog((event[event.length - 1].event.data.toJSON() as any)[2][0]);
await expect(schedule.cancelCall(ethers.utils.hexlify(decode_log.args.task_id)))
.to.emit(schedule, 'CanceledCall')
.withArgs(await wallet.getAddress(), ethers.utils.hexlify(decode_log.args.task_id));
});
it('RescheduleCall works', async () => {
const erc20 = new ethers.Contract(ADDRESS.DOT, ERC20_ABI, walletTo as any);
const tx = await erc20.populateTransaction.transfer(walletTo.getAddress(), 1_000_000);
// console.log(tx, ethers.utils.hexlify(tx.data as string));
let iface = new ethers.utils.Interface(SCHEDULE_CALL_ABI);
let current_block_number = Number(await provider.api.query.system.number());
await schedule.scheduleCall(ADDRESS.DOT, 0, 300000, 10000, 4, ethers.utils.hexlify(tx.data as string));
let block_hash = await provider.api.rpc.chain.getBlockHash(current_block_number + 1);
const data = await provider.api.derive.tx.events(block_hash);
let event = data.events.filter((item) => provider.api.events.evm.Executed.is(item.event));
expect(event.length).above(0);
let decode_log = iface.parseLog((event[event.length - 1].event.data.toJSON() as any)[2][0]);
await expect(schedule.rescheduleCall(5, ethers.utils.hexlify(decode_log.args.task_id)))
.to.emit(schedule, 'RescheduledCall')
.withArgs(await wallet.getAddress(), ethers.utils.hexlify(decode_log.args.task_id));
});
it('works with RecurringPayment', async () => {
const erc20 = new ethers.Contract(ADDRESS.ACA, ERC20_ABI, walletTo as any);
const transferTo = await ethers.Wallet.createRandom().getAddress();
const recurringPayment = await deployContract(
wallet as any,
RecurringPayment,
[3, 4, ethers.utils.parseEther('1000'), transferTo],
{ gasLimit: 2_000_000 }
);
// ACA as erc20 decimals is 12
await erc20.transfer(recurringPayment.address, dollar.mul(5000));
const inital_block_number = Number(await provider.api.query.system.number());
await recurringPayment.initialize();
expect((await provider.getBalance(transferTo)).toString()).to.equal('0');
expect((await erc20.balanceOf(transferTo)).toString()).to.equal('0');
let current_block_number = Number(await provider.api.query.system.number());
while (current_block_number < inital_block_number + 5) {
await next_block(current_block_number);
current_block_number = Number(await provider.api.query.system.number());
}
expect((await provider.getBalance(transferTo)).toString()).to.equal(dollar.mul(1000000000).toString());
expect((await erc20.balanceOf(transferTo)).toString()).to.equal(dollar.mul(1000).toString());
current_block_number = Number(await provider.api.query.system.number());
while (current_block_number < inital_block_number + 14) {
await next_block(current_block_number);
current_block_number = Number(await provider.api.query.system.number());
}
expect((await provider.getBalance(transferTo)).toString()).to.equal(dollar.mul(3000000000).toString());
expect((await erc20.balanceOf(transferTo)).toString()).to.equal(dollar.mul(3000).toString());
current_block_number = Number(await provider.api.query.system.number());
while (current_block_number < inital_block_number + 17) {
await next_block(current_block_number);
current_block_number = Number(await provider.api.query.system.number());
}
expect((await provider.getBalance(recurringPayment.address)).toString()).to.equal('0');
expect((await erc20.balanceOf(recurringPayment.address)).toNumber()).to.equal(0);
if (!process.argv.includes('--with-ethereum-compatibility')) {
expect((await provider.getBalance(transferTo)).toString()).to.equal(
formatAmount('4_999_969_076_152_000_000_000')
);
expect((await erc20.balanceOf(transferTo)).toString()).to.equal(formatAmount('4_999_969_076_152_000'));
} else {
expect((await provider.getBalance(transferTo)).toString()).to.equal(dollar.mul(5000000000).toString());
expect((await erc20.balanceOf(transferTo)).toString()).to.equal(dollar.mul(5000).toString());
}
});
it('works with Subscription', async () => {
const period = 10;
const subPrice = ethers.utils.parseEther('1000');
const subscription = await deployContract(wallet as any, Subscription, [subPrice, period], {
value: ethers.utils.parseEther('5000'),
gasLimit: 2_000_000
});
if (!process.argv.includes('--with-ethereum-compatibility')) {
// If it is not called by the maintainer, developer, or contract, it needs to be deployed first
await provider.api.tx.evm.publishContract(subscription.address).signAndSend(testPairs.alice.address);
}
expect((await subscription.balanceOf(subscriber.getAddress())).toString()).to.equal('0');
expect((await subscription.subTokensOf(subscriber.getAddress())).toString()).to.equal('0');
expect((await subscription.monthsSubscribed(subscriber.getAddress())).toString()).to.equal('0');
const subscriberContract = subscription.connect(subscriber as any);
await subscriberContract.subscribe({
value: ethers.utils.parseEther(formatAmount('10_000')).toString(),
gasLimit: 2_000_000
});
expect((await subscription.balanceOf(subscriber.getAddress())).toString()).to.equal(
ethers.utils.parseEther(formatAmount('10_000')).sub(subPrice).toString()
);
expect((await subscription.subTokensOf(subscriber.getAddress())).toString()).to.equal('1');
expect((await subscription.monthsSubscribed(subscriber.getAddress())).toString()).to.equal('1');
let current_block_number = Number(await provider.api.query.system.number());
for (let i = 0; i < period + 1; i++) {
await next_block(current_block_number);
current_block_number = Number(await provider.api.query.system.number());
}
expect((await subscription.balanceOf(subscriber.getAddress())).toString()).to.equal(
ethers.utils.parseEther(formatAmount('10_000')).sub(subPrice.mul(2)).toString()
);
expect((await subscription.subTokensOf(subscriber.getAddress())).toString()).to.equal('3');
expect((await subscription.monthsSubscribed(subscriber.getAddress())).toString()).to.equal('2');
current_block_number = Number(await provider.api.query.system.number());
for (let i = 0; i < period + 1; i++) {
await next_block(current_block_number);
current_block_number = Number(await provider.api.query.system.number());
}
expect((await subscription.balanceOf(subscriber.getAddress())).toString()).to.equal(
ethers.utils.parseEther(formatAmount('10_000')).sub(subPrice.mul(3)).toString()
);
expect((await subscription.subTokensOf(subscriber.getAddress())).toString()).to.equal('6');
expect((await subscription.monthsSubscribed(subscriber.getAddress())).toString()).to.equal('3');
await subscriberContract.unsubscribe({ gasLimit: 2_000_000 });
current_block_number = Number(await provider.api.query.system.number());
await next_block(current_block_number);
expect((await subscription.balanceOf(subscriber.getAddress())).toString()).to.equal('0');
expect((await subscription.subTokensOf(subscriber.getAddress())).toString()).to.equal('6');
expect((await subscription.monthsSubscribed(subscriber.getAddress())).toString()).to.equal('0');
});
});
Example #29
Source File: multicall2.test.ts From useDApp with MIT License | 4 votes |
describe('Multicall2', () => {
const mockProvider = new MockProvider()
const [deployer] = mockProvider.getWallets()
let tokenContract: Contract
let multicallContract: Contract
beforeEach(async () => {
const args = ['MOCKToken', 'MOCK', deployer.address, '10000']
tokenContract = await deployContract(deployer, ERC20Mock, args)
multicallContract = await deployContract(deployer, MultiCall2)
})
for (const fastEncoding of [false, true]) {
describe(fastEncoding ? 'Fast encoding' : 'Ethers encoding', () => {
const multicall2 = multicall2Factory(fastEncoding)
it('Retrieves token balance using tryAggregate', async () => {
const data = new Interface(ERC20Mock.abi).encodeFunctionData('balanceOf', [deployer.address])
const call: RawCall = {
address: tokenContract.address,
data,
chainId: mockProvider._network.chainId,
}
const blockNumber = await mockProvider.getBlockNumber()
const result = await multicall2(mockProvider, multicallContract.address, blockNumber, [call])
const { value, success } = result[tokenContract.address]![data] || {}
expect(success).to.be.true
expect(BigNumber.from(value)).to.eq('10000')
})
it('Fails to retrieve data on block number in the future', async () => {
const data = new Interface(ERC20Mock.abi).encodeFunctionData('balanceOf', [deployer.address])
const call: RawCall = {
address: tokenContract.address,
data,
chainId: mockProvider._network.chainId,
}
const blockNumber = (await mockProvider.getBlockNumber()) + 1
await expect(multicall2(mockProvider, multicallContract.address, blockNumber, [call])).to.be.eventually.rejected
})
it('Does not fail when retrieving data on block number from the past', async () => {
const data = new Interface(ERC20Mock.abi).encodeFunctionData('balanceOf', [deployer.address])
const call: RawCall = {
address: tokenContract.address,
data,
chainId: mockProvider._network.chainId,
}
await sendEmptyTx(deployer)
const blockNumber = (await mockProvider.getBlockNumber()) - 1
const result = await multicall2(mockProvider, multicallContract.address, blockNumber, [call])
const { value, success } = result[tokenContract.address]![data] || {}
expect(success).to.be.true
expect(BigNumber.from(value)).to.eq('10000')
})
it('Does not fail when doing multiple calls at once', async () => {
const erc20Interface = new Interface(ERC20Mock.abi)
const calls: RawCall[] = [
{
address: tokenContract.address,
data: erc20Interface.encodeFunctionData('balanceOf', [deployer.address]),
chainId: mockProvider._network.chainId,
},
{
address: tokenContract.address,
data: erc20Interface.encodeFunctionData('symbol', []),
chainId: mockProvider._network.chainId,
},
{
address: tokenContract.address,
data: erc20Interface.encodeFunctionData('balanceOf', [tokenContract.address]),
chainId: mockProvider._network.chainId,
},
]
const blockNumber = await mockProvider.getBlockNumber()
const result = await multicall2(mockProvider, multicallContract.address, blockNumber, calls)
let { value, success } = result[calls[0].address]![calls[0].data] || {}
expect(value).to.equal(BigNumber.from(10000))
expect(success).to.be.true
;({ value, success } = result[calls[1].address]![calls[1].data] || {})
const decodedSymbol = utils.defaultAbiCoder.decode(['string'], value!)[0]
expect(decodedSymbol).to.equal('MOCK')
expect(success).to.be.true
;({ value, success } = result[calls[2].address]![calls[2].data] || {})
expect(value).to.equal(BigNumber.from(0))
expect(success).to.be.true
})
it('Does not fail when some of the calls fail', async () => {
const erc20Interface = new Interface(ERC20Mock.abi)
const calls: RawCall[] = [
{
address: tokenContract.address,
data: erc20Interface.encodeFunctionData('balanceOf', [deployer.address]),
chainId: mockProvider._network.chainId,
},
// invalid one
{
address: tokenContract.address,
data: erc20Interface.encodeFunctionData('transferFrom', [
multicallContract.address,
deployer.address,
BigNumber.from(10000),
]),
chainId: mockProvider._network.chainId,
},
{
address: tokenContract.address,
data: erc20Interface.encodeFunctionData('balanceOf', [tokenContract.address]),
chainId: mockProvider._network.chainId,
},
]
const blockNumber = await mockProvider.getBlockNumber()
const result = await multicall2(mockProvider, multicallContract.address, blockNumber, calls)
let { value, success } = result[calls[0].address]![calls[0].data] || {}
expect(value).to.equal(BigNumber.from(10000))
expect(success).to.be.true
;({ value, success } = result[calls[1].address]![calls[1].data] || {})
const decodedValue = new utils.Interface(['function Error(string)']).decodeFunctionData('Error', value!)[0]
expect(decodedValue).to.equal('ERC20: transfer amount exceeds balance')
expect(success).to.be.false
;({ value, success } = result[calls[2].address]![calls[2].data] || {})
expect(value).to.equal(BigNumber.from(0))
expect(success).to.be.true
})
})
}
})