Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions contracts/TestCurrency.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,29 @@
pragma solidity ^0.8.0;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";

contract TestCurrency is ERC20, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

contract TestCurrency is ERC20 {
uint8 internal immutable _decimals;

constructor(
string memory name_,
string memory symbol_,
uint256 initialSupply,
uint8 decimals_,
address admin
uint8 decimals_
) ERC20(name_, symbol_) {
_decimals = decimals_;
_mint(msg.sender, initialSupply);
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}

function decimals() public view virtual override returns (uint8) {
return _decimals;
}

function mint(address recipient, uint256 amount) external onlyRole(MINTER_ROLE) {
// require(msg.sender == _owner, "Only owner can mint");
function mint(address recipient, uint256 amount) public virtual {
return _mint(recipient, amount);
}

function burn(address recipient, uint256 amount) external onlyRole(BURNER_ROLE) {
// require(msg.sender == _owner, "Only owner can burn");
function burn(address recipient, uint256 amount) public virtual {
return _burn(recipient, amount);
}
}
28 changes: 28 additions & 0 deletions contracts/TestCurrencyAC.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {TestCurrency} from "./TestCurrency.sol";

contract TestCurrencyAC is TestCurrency, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

constructor(
string memory name_,
string memory symbol_,
uint256 initialSupply,
uint8 decimals_,
address admin
) TestCurrency(name_, symbol_, initialSupply, decimals_) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}

function mint(address recipient, uint256 amount) public override onlyRole(MINTER_ROLE) {
super.mint(recipient, amount);
}

function burn(address recipient, uint256 amount) public override onlyRole(BURNER_ROLE) {
super.burn(recipient, amount);
}
}
10 changes: 7 additions & 3 deletions contracts/TestERC4626.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ pragma solidity ^0.8.0;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC4626} from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {TestCurrency} from "./TestCurrency.sol";

interface IMintable {
function mint(address recipient, uint256 amount) external;
function burn(address recipient, uint256 amount) external;
}

contract TestERC4626 is ERC4626 {
bool internal _broken;
Expand Down Expand Up @@ -58,9 +62,9 @@ contract TestERC4626 is ERC4626 {
*/
function discreteEarning(int256 assets) external {
if (assets > 0) {
TestCurrency(asset()).mint(address(this), uint256(assets));
IMintable(asset()).mint(address(this), uint256(assets));
} else {
TestCurrency(asset()).burn(address(this), uint256(-assets));
IMintable(asset()).burn(address(this), uint256(-assets));
}
}

Expand Down
5 changes: 4 additions & 1 deletion js/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ const { Assertion } = require("chai");
const { ethers } = hre;

async function initCurrency(options, initial_targets, initial_balances) {
const Currency = await ethers.getContractFactory(options.contractClass || "TestCurrency");
const extraArgs = options.extraArgs || [];
const Currency = await ethers.getContractFactory(
options.contractClass || (extraArgs.length == 0 ? "TestCurrency" : "TestCurrencyAC")
);
let currency = await Currency.deploy(
options.name || "Test Currency",
options.symbol || "TEST",
Expand Down
31 changes: 27 additions & 4 deletions test/test-utils-functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ describe("Utils library tests", function () {
[, anon, admin, user1, user2] = await ethers.getSigners();
});

async function deployFixture() {
async function deployACFixture() {
// Fixture with TestCurrencyAC (with access control)
const currency = await initCurrency(
{ name: "Test USDC", symbol: "USDC", decimals: 6, initial_supply: _A(50000), extraArgs: [admin] },
[anon, user1, user2, admin],
Expand All @@ -24,8 +25,19 @@ describe("Utils library tests", function () {
return { currency };
}

it("Checks only MINTER_ROLE can mint", async () => {
const { currency } = await helpers.loadFixture(deployFixture);
async function deployFixture() {
// Fixture with TestCurrency (without access control)
const currency = await initCurrency(
{ name: "Test USDC", symbol: "USDC", decimals: 6, initial_supply: _A(50000) },
[anon, user1, user2, admin],
[_A("10000"), _A("2000"), _A("1000"), _A("20000")]
);

return { currency };
}

it("Checks only MINTER_ROLE can mint (TestCurrencyAC)", async () => {
const { currency } = await helpers.loadFixture(deployACFixture);

expect(await currency.balanceOf(anon)).to.equal(_A(10000));

Expand All @@ -40,11 +52,22 @@ describe("Utils library tests", function () {
expect(await currency.balanceOf(anon)).to.equal(_A(10100));
});

it("Checks TestERC4626", async () => {
it("Checks anyone can mint and burnd (TestCurrency)", async () => {
const { currency } = await helpers.loadFixture(deployFixture);

expect(await currency.balanceOf(anon)).to.equal(_A(10000));

await expect(currency.connect(admin).mint(anon, _A(100))).not.to.be.reverted;
expect(await currency.balanceOf(anon)).to.equal(_A(10100));
await expect(currency.connect(admin).burn(anon, _A(150))).not.to.be.reverted;
expect(await currency.balanceOf(anon)).to.equal(_A(9950));
});

it("Checks TestERC4626", async () => {
const { currency } = await helpers.loadFixture(deployACFixture);

expect(await currency.balanceOf(anon)).to.equal(_A(10000));

const TestERC4626 = await ethers.getContractFactory("TestERC4626");
const vault = await TestERC4626.deploy("Test", "TEST", currency);

Expand Down
Loading