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

Tests/deposit lib #303

Merged
merged 3 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
27 changes: 27 additions & 0 deletions packages/govern-contract-utils/contracts/test/DepositLibMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SPDX-License-Identifier: MIT
*/

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;

import "../deposits/DepositLib.sol";
import "erc3k/contracts/ERC3000Data.sol";

contract DepositLibMock {
// Below two events are duplicated from the DepositLib library to make sure that this contract
// contains the Locked/Unlocked event in its own abi in order to test if the events were thrown or not.
// For more info: https://github.com/ethereum/solidity/pull/10996
event Locked(address indexed token, address indexed from, uint256 amount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not correctly intended (line 15-18)

event Unlocked(address indexed token, address indexed to, uint256 amount);

using DepositLib for ERC3000Data.Collateral;

function collectFrom(ERC3000Data.Collateral memory _collateral, address _from) public {
_collateral.collectFrom(_from);
}

function releaseTo(ERC3000Data.Collateral memory _collateral, address _to) public {
_collateral.releaseTo(_to);
}
}
119 changes: 119 additions & 0 deletions packages/govern-contract-utils/test/deposit-lib.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { expect } from 'chai'
import { ethers } from 'hardhat'

import {
DepositLibMock, DepositLibMock__factory,
GoodToken, GoodToken__factory
} from '../typechain'

const EVENTS = {
LOCKED: 'Locked',
UNLOCKED: 'Unlocked',
TRANSFER: 'Transfer'
}

const ERRORS = {
BAD_TOKEN_LOCK: "deposit: bad token lock",
BAD_TOKEN_RELEASE: "deposit: bad token release"
}

const amount = 1000

describe('DepositLib', function () {
let depositLibMock: DepositLibMock
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done with one let keyword

let goodToken: GoodToken
let owner: any;

before(async () => {
const DepositLibMockFactory = (await ethers.getContractFactory('DepositLibMock')) as DepositLibMock__factory
depositLibMock = await DepositLibMockFactory.deploy()

owner = await (await ethers.getSigners())[0].getAddress()
})


describe('collectFrom', async () => {
before(async () => {
const GoodTokenFactory = (await ethers.getContractFactory('GoodToken')) as GoodToken__factory
goodToken = await GoodTokenFactory.deploy();
})

it("reverts if the token in the collateral is not a contract", async () => {
const deposit = {
token: owner,
amount: amount,
}
await expect(depositLibMock.collectFrom(deposit, owner)).to.be.revertedWith(ERRORS.BAD_TOKEN_LOCK)
})

it("reverts if the token's `from` address doesn't have approval for `to` address", async () => {
const deposit = {
token: goodToken.address,
amount: amount,
}

await expect(depositLibMock.collectFrom(deposit, owner)).to.be.revertedWith(ERRORS.BAD_TOKEN_LOCK)
})

it("successfully makes the transfer and emits the events", async () => {
const deposit = {
token: goodToken.address,
amount: amount,
}

await goodToken.setBalanceTo(owner, amount);

let tx =await depositLibMock.collectFrom(deposit, owner);

await expect(tx)
.to.emit(goodToken, EVENTS.TRANSFER)
.withArgs(owner, depositLibMock.address, amount)
.to.emit(depositLibMock, EVENTS.LOCKED)
.withArgs(goodToken.address, owner, amount)
})
})


describe('releaseTo', async () => {
before(async () => {
const GoodTokenFactory = (await ethers.getContractFactory('GoodToken')) as GoodToken__factory
goodToken = await GoodTokenFactory.deploy();
})

it("reverts if the token in the collateral is not a contract", async () => {
const deposit = {
token: owner,
amount: amount,
}
await expect(depositLibMock.releaseTo(deposit, owner)).to.be.revertedWith(ERRORS.BAD_TOKEN_RELEASE)
})

it("reverts if the contract doesn't have enough balance to make the transfer", async () => {
const deposit = {
token: goodToken.address,
amount: amount,
}

await expect(depositLibMock.releaseTo(deposit, owner)).to.be.revertedWith(ERRORS.BAD_TOKEN_RELEASE)
})

it("successfully makes the transfer and emits the events", async () => {
const deposit = {
token: goodToken.address,
amount: amount,
}

await goodToken.setBalanceTo(depositLibMock.address, amount);

let tx = depositLibMock.releaseTo(deposit, owner);

// TODO: the chaining turns out to be wrong. if the first withArgs fail, and the second withArgs doesn't fail,
// the below throws unhandledPromiseRejection and says that they are not equal, but doesn't make the tests fail.
await expect(tx)
.to.emit(goodToken, EVENTS.TRANSFER)
.withArgs(depositLibMock.address, owner, amount)
.to.emit(depositLibMock, EVENTS.UNLOCKED)
.withArgs(goodToken.address, owner, amount)
})
})
})