-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* update(docs): upgraded OZ packages to latest version 5.0.0 Signed-off-by: Logan Nguyen <[email protected]> * update: removed ERC20SnapshotMock contract Signed-off-by: Logan Nguyen <[email protected]> * update: replaced OZ/SafeMath.sol to OZ/Math.sol Signed-off-by: Logan Nguyen <[email protected]> * fix: replaced _getImplementation() with ERC1967Utils.getImplementation(); Signed-off-by: Logan Nguyen <[email protected]> * fix: passed arguments to the new Ownable base constructor Signed-off-by: Logan Nguyen <[email protected]> * fix: fixed warnings Signed-off-by: Logan Nguyen <[email protected]> * update: re-compiled all contracts Signed-off-by: Logan Nguyen <[email protected]> * WIP. Adding tests around the OZ ERC-4626 Token vault example. Signed-off-by: ebadiere <[email protected]> * WIP. Completed coverage. Needs to be updated to run against the local node. Signed-off-by: ebadiere <[email protected]> * Updates to contract revert tests to check encoded transaction data until a solution for returning the contract revert reason is found. Signed-off-by: ebadiere <[email protected]> * Updated contract revert issue to the relay issue. #1916 getTransactionReceipt Signed-off-by: ebadiere <[email protected]> * Applied feedback Signed-off-by: ebadiere <[email protected]> * Set the revert reasons on. Signed-off-by: ebadiere <[email protected]> * Refactored to evaulate the results of eth_estimateGase. Signed-off-by: ebadiere <[email protected]> * Removed two tests that covered zero deposit and withdraw amounts, as they may be confusing depending on what node they are running against. Signed-off-by: ebadiere <[email protected]> * Cleaned up label. Signed-off-by: ebadiere <[email protected]> --------- Signed-off-by: Logan Nguyen <[email protected]> Signed-off-by: ebadiere <[email protected]> Co-authored-by: Logan Nguyen <[email protected]>
- Loading branch information
1 parent
5804b9d
commit 81df819
Showing
7 changed files
with
153 additions
and
56 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
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,61 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import "../../erc-20/ERC20Mock.sol"; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; | ||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
|
||
|
||
contract TokenVault is ERC4626 { | ||
|
||
// a mapping that checks if a user has deposited the token | ||
mapping(address => uint256) public shareHolders; | ||
|
||
constructor( | ||
IERC20 _asset, | ||
string memory _name, | ||
string memory _symbol | ||
) ERC4626(_asset) ERC20(_name, _symbol) { | ||
|
||
} | ||
|
||
function _deposit(uint256 _assets) public { | ||
// checks that the deposited amount is greater than zero. | ||
require(_assets > 0, "Deposit is zero"); | ||
// calling the deposit function from the ERC-4626 library to perform all the necessary functionality | ||
deposit(_assets, msg.sender); | ||
// Increase the share of the user | ||
shareHolders[msg.sender] += _assets; | ||
} | ||
|
||
function _withdraw(uint256 _shares, address _receiver) public { | ||
// checks that the deposited amount is greater than zero. | ||
require(_shares > 0, "withdraw must be greater than Zero"); | ||
// Checks that the _receiver address is not zero. | ||
require(_receiver != address(0), "Zero Address"); | ||
// checks that the caller is a shareholder | ||
require(shareHolders[msg.sender] > 0, "Not a shareHolder"); | ||
// checks that the caller has more shares than they are trying to withdraw. | ||
require(shareHolders[msg.sender] >= _shares, "Not enough shares"); | ||
// Calculate 10% yield on the withdraw amount | ||
uint256 percent = (10 * _shares) / 100; | ||
// Calculate the total asset amount as the sum of the share amount plus 10% of the share amount. | ||
uint256 assets = _shares + percent; | ||
// Decrease the share of the user | ||
shareHolders[msg.sender] -= _shares; | ||
// calling the redeem function from the ERC-4626 library to perform all the necessary functionality | ||
redeem(assets, _receiver, msg.sender); | ||
} | ||
|
||
// returns total number of assets | ||
function totalAssets() public view override returns (uint256) { | ||
return super.totalAssets(); | ||
} | ||
|
||
function totalAssetsOfUser(address _user) public view returns (uint256) { | ||
return shareHolders[_user]; | ||
} | ||
|
||
} |
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,92 @@ | ||
const { expect } = require("chai"); | ||
const { ethers } = require("hardhat"); | ||
const Constants = require('../../constants') | ||
|
||
describe("@OZ TokenVault Contract", function () { | ||
let TokenVault; | ||
let tokenVault; | ||
let ERC20Mock; | ||
let asset; | ||
let owner; | ||
let addr1; | ||
let addr2; | ||
let addrs; | ||
|
||
beforeEach(async function () { | ||
ERC20Mock = await ethers.getContractFactory("contracts/erc-20/ERC20Mock.sol:ERC20Mock"); | ||
asset = await ERC20Mock.deploy("MockToken", "MTK", Constants.GAS_LIMIT_1_000_000); | ||
await asset.deployed(); | ||
|
||
TokenVault = await ethers.getContractFactory("TokenVault"); | ||
tokenVault = await TokenVault.deploy(asset.address, "MockToken", "MTK", Constants.GAS_LIMIT_1_000_000); | ||
await tokenVault.deployed(); | ||
|
||
[owner, addr1, addr2, ...addrs] = await ethers.getSigners(); | ||
|
||
await asset.mint(addr1.address, ethers.utils.parseUnits("1000", 18)); | ||
await asset.mint(addr2.address, ethers.utils.parseUnits("10", 18)); | ||
|
||
}); | ||
|
||
describe("Deployment", function () { | ||
it("Should assign the total supply of tokens to the owner", async function () { | ||
const ownerBalance = await tokenVault.balanceOf(owner.address); | ||
expect(await tokenVault.totalSupply()).to.equal(ownerBalance); | ||
}); | ||
}); | ||
|
||
describe("Transactions", function () { | ||
it("Should deposit tokens and update shareHolders mapping", async function () { | ||
const depositAmount = ethers.utils.parseEther("10"); | ||
await asset.connect(addr1).approve(tokenVault.address, depositAmount); | ||
await expect(tokenVault.connect(addr1)._deposit(depositAmount)) | ||
.to.emit(tokenVault, "Deposit") | ||
.withArgs(addr1.address, addr1.address, depositAmount, depositAmount); | ||
|
||
expect(await tokenVault.shareHolders(addr1.address)).to.equal(depositAmount); | ||
}); | ||
|
||
it("Should withdraw tokens and update shareHolders mapping", async function () { | ||
const depositAmount = ethers.utils.parseEther("10"); | ||
const withdrawAmount = ethers.utils.parseEther("5"); | ||
const redemedAmount = ethers.utils.parseEther("5.5"); | ||
|
||
await asset.connect(addr2).approve(tokenVault.address, depositAmount); | ||
await tokenVault.connect(addr2)._deposit(depositAmount); | ||
|
||
await expect(tokenVault.connect(addr2)._withdraw(withdrawAmount, addr2.address)) | ||
.to.emit(tokenVault, "Withdraw") | ||
.withArgs(addr2.address, addr2.address, addr2.address, redemedAmount, redemedAmount); | ||
|
||
expect(await tokenVault.totalAssetsOfUser(addr2.address)).to.equal(depositAmount.sub(withdrawAmount)); | ||
}); | ||
|
||
it("Should fail if withdraw is to zero address", async function () { | ||
expect(await tokenVault.connect(addr1)._withdraw(1, ethers.constants.AddressZero)).to.be.revertedWith("Zero Address"); | ||
}); | ||
|
||
it("Should fail if not a shareholder", async function () { | ||
expect(await tokenVault.connect(addr2)._withdraw(1, addr2.address)).to.be.revertedWith("Not a shareHolder"); | ||
}); | ||
|
||
it("Should fail if not enough shares", async function () { | ||
const depositAmount = ethers.utils.parseEther("10"); | ||
await asset.connect(addr1).approve(tokenVault.address, depositAmount); | ||
await tokenVault.connect(addr1)._deposit(depositAmount); | ||
expect(await tokenVault.connect(addr1)._withdraw(depositAmount.add(1), addr1.address)).to.be.revertedWith("Not enough shares"); | ||
}); | ||
|
||
}); | ||
|
||
describe("Views", function () { | ||
|
||
it("Should return the total assets of a user", async function () { | ||
const depositAmount = ethers.utils.parseEther("10"); | ||
await asset.connect(addr1).approve(tokenVault.address, depositAmount); | ||
await tokenVault.connect(addr1)._deposit(depositAmount); | ||
|
||
expect(await tokenVault.totalAssetsOfUser(addr1.address)).to.equal(depositAmount); | ||
}); | ||
}); | ||
|
||
}); |