-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: adds tests to VotiumBribeForwarder (#303)
* test: adds tests to VotiumBribeForwarder * test: adds tests to DisperseForwarder * chore:fix eslint issues on emissions controller files
- Loading branch information
1 parent
5c794bd
commit 5d57eae
Showing
10 changed files
with
326 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.6; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import { IDisperse } from "../../interfaces/IDisperse.sol"; | ||
|
||
contract MockDisperse is IDisperse { | ||
function disperseTokenSimple( | ||
IERC20 token, | ||
address[] calldata recipients, | ||
uint256[] calldata values | ||
) external override { | ||
for (uint256 i = 0; i < recipients.length; i++) { | ||
// solhint-disable-next-line reason-string | ||
require(token.transferFrom(msg.sender, recipients[i], values[i])); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.6; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | ||
import { IVotiumBribe } from "../../interfaces/IVotiumBribe.sol"; | ||
|
||
contract MockVotiumBribe is IVotiumBribe { | ||
using SafeERC20 for IERC20; | ||
|
||
address public feeAddress = 0xe39b8617D571CEe5e75e1EC6B2bb40DdC8CF6Fa3; // Votium multisig | ||
event Bribed(address _token, uint256 _amount, bytes32 indexed _proposal, uint256 _choiceIndex); | ||
|
||
function depositBribe( | ||
address _token, | ||
uint256 _amount, | ||
bytes32 _proposal, | ||
uint256 _choiceIndex | ||
) external override { | ||
uint256 fee = 0; | ||
uint256 bribeTotal = _amount - fee; | ||
// Sends the fee to votium multisig | ||
IERC20(_token).safeTransferFrom(msg.sender, feeAddress, fee); | ||
// if distributor contract is not set, store in this contract until ready | ||
IERC20(_token).safeTransferFrom(msg.sender, address(this), bribeTotal); | ||
|
||
emit Bribed(_token, bribeTotal, _proposal, _choiceIndex); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { MAX_UINT256, ZERO_ADDRESS } from "@utils/constants" | ||
import { MassetMachine, StandardAccounts } from "@utils/machines" | ||
import { simpleToExactAmount } from "@utils/math" | ||
import { expect } from "chai" | ||
import { ethers } from "hardhat" | ||
import { Account } from "types/common" | ||
import { | ||
MockERC20, | ||
MockNexus, | ||
MockNexus__factory, | ||
MockDisperse, | ||
MockDisperse__factory, | ||
DisperseForwarder, | ||
DisperseForwarder__factory, | ||
} from "types/generated" | ||
|
||
describe("DisperseForwarder", () => { | ||
let sa: StandardAccounts | ||
let mAssetMachine: MassetMachine | ||
let nexus: MockNexus | ||
let rewardsToken: MockERC20 | ||
let owner: Account | ||
let emissionsController: Account | ||
let forwarder: DisperseForwarder | ||
let disperse: MockDisperse | ||
|
||
/* | ||
Test Data | ||
mAssets: mUSD and mBTC with 18 decimals | ||
*/ | ||
const setup = async (): Promise<void> => { | ||
// Deploy mock Nexus | ||
nexus = await new MockNexus__factory(sa.default.signer).deploy( | ||
sa.governor.address, | ||
sa.mockSavingsManager.address, | ||
sa.mockInterestValidator.address, | ||
) | ||
// Deploy mock Disperse | ||
disperse = await new MockDisperse__factory(sa.default.signer).deploy() | ||
|
||
rewardsToken = await mAssetMachine.loadBassetProxy("Rewards Token", "RWD", 18) | ||
owner = sa.default | ||
emissionsController = sa.dummy2 | ||
|
||
// Deploy DisperseForwarder | ||
forwarder = await new DisperseForwarder__factory(owner.signer).deploy(nexus.address, rewardsToken.address, disperse.address) | ||
|
||
await rewardsToken.transfer(emissionsController.address, simpleToExactAmount(10000)) | ||
await rewardsToken.connect(emissionsController.signer).approve(forwarder.address, MAX_UINT256) | ||
} | ||
|
||
before(async () => { | ||
const accounts = await ethers.getSigners() | ||
mAssetMachine = await new MassetMachine().initAccounts(accounts) | ||
sa = mAssetMachine.sa | ||
await setup() | ||
}) | ||
|
||
describe("creating new instance", () => { | ||
it("should have immutable variables set", async () => { | ||
expect(await forwarder.nexus(), "Nexus").eq(nexus.address) | ||
expect(await forwarder.REWARDS_TOKEN(), "rewards token").eq(rewardsToken.address) | ||
expect(await forwarder.DISPERSE(), "disperse contract").eq(disperse.address) | ||
}) | ||
describe("it should fail if zero", () => { | ||
it("nexus", async () => { | ||
const tx = new DisperseForwarder__factory(sa.default.signer).deploy(ZERO_ADDRESS, rewardsToken.address, disperse.address) | ||
await expect(tx).to.revertedWith("Nexus address is zero") | ||
}) | ||
it("rewards token", async () => { | ||
const tx = new DisperseForwarder__factory(sa.default.signer).deploy(nexus.address, ZERO_ADDRESS, disperse.address) | ||
await expect(tx).to.revertedWith("Invalid Rewards token") | ||
}) | ||
it("disperse contract ", async () => { | ||
const tx = new DisperseForwarder__factory(sa.default.signer).deploy(nexus.address, rewardsToken.address, ZERO_ADDRESS) | ||
await expect(tx).to.revertedWith("Invalid Disperse contract") | ||
}) | ||
}) | ||
}) | ||
describe("disperse token", () => { | ||
it("should transfer rewards to forwarder", async () => { | ||
const recipients = [disperse.address] | ||
const values = [simpleToExactAmount(100, 18)] | ||
|
||
const endRecipientBalBefore = await rewardsToken.balanceOf(disperse.address) | ||
const amount = simpleToExactAmount(100, 18) | ||
// Simulate the emissions controller calling the forwarder | ||
await rewardsToken.transfer(forwarder.address, amount) | ||
|
||
await forwarder.connect(sa.governor.signer).disperseToken(recipients, values) | ||
|
||
// check output balances: mAsset sender/recipient | ||
expect(await rewardsToken.balanceOf(disperse.address), "end recipient balance after").eq(endRecipientBalBefore.add(amount)) | ||
}) | ||
describe("should fail if", () => { | ||
it("recipients and values do not match", async () => { | ||
const recipients = [disperse.address] | ||
const tx = forwarder.connect(sa.governor.signer).disperseToken(recipients, []) | ||
await expect(tx).to.be.revertedWith("array mismatch") | ||
}) | ||
it("balance is insufficient", async () => { | ||
const balance = await rewardsToken.balanceOf(forwarder.address) | ||
const tx = forwarder.connect(sa.governor.signer).disperseToken([disperse.address, disperse.address], [balance, 1]) | ||
await expect(tx).to.be.revertedWith("Insufficient rewards") | ||
}) | ||
it("non governor or keeper", async () => { | ||
const recipients = [disperse.address] | ||
const values = [simpleToExactAmount(100, 18)] | ||
const tx = forwarder.disperseToken(recipients, values) | ||
await expect(tx).to.be.revertedWith("Only keeper or governor") | ||
}) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.