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

Add tests to the Vault, deploy new Vault for negative cases, refactor contracts and tests #21

Merged
merged 6 commits into from
Apr 16, 2024
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
2 changes: 2 additions & 0 deletions contracts/erc4626/IERC4626.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ abstract contract IERC4626 is ERC20 {
event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);
event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);

error ZeroShares(uint256 numberOfShares);

/*///////////////////////////////////////////////////////////////
Mutable Functions
//////////////////////////////////////////////////////////////*/
Expand Down
66 changes: 58 additions & 8 deletions contracts/erc4626/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@ contract HederaVault is IERC4626 {
using Bits for uint256;

ERC20 public immutable asset;
address newTokenAddress;
address public newTokenAddress;
uint public totalTokens;
address[] tokenAddress;
address[] public tokenAddress;
address public owner;

event createdToken(address indexed createdTokenAddress);
/**
* @notice CreatedToken event.
* @dev Emitted after contract initialization, when represented shares token is deployed.
*
* @param createdToken The address of created token.
*/
event CreatedToken(address indexed createdToken);

constructor(
ERC20 _underlying,
string memory _name,
string memory _symbol
) payable ERC20(_name, _symbol, _underlying.decimals()) {
owner = msg.sender;

SafeHTS.safeAssociateToken(address(_underlying), address(this));
uint256 supplyKeyType;
uint256 adminKeyType;
Expand Down Expand Up @@ -56,7 +64,7 @@ contract HederaVault is IERC4626 {
newToken.expiry = expiry;
newToken.tokenKeys = keys;
newTokenAddress = SafeHTS.safeCreateFungibleToken(newToken, 0, _underlying.decimals());
emit createdToken(newTokenAddress);
emit CreatedToken(newTokenAddress);
asset = _underlying;
}

Expand All @@ -78,10 +86,15 @@ contract HederaVault is IERC4626 {
DEPOSIT/WITHDRAWAL LOGIC
//////////////////////////////////////////////////////////////*/

/**
* @dev Deposits staking token to the Vault and returns shares.
*
* @param amount The amount of staking token to send.
* @param to The shares receiver address.
* @return shares The amount of shares to receive.
*/
function deposit(uint256 amount, address to) public override returns (uint256 shares) {
require((shares = previewDeposit(amount)) != 0, "ZERO_SHARES");

asset.approve(address(this), amount);
if ((shares = previewDeposit(amount)) == 0) revert ZeroShares(amount);

asset.safeTransferFrom(msg.sender, address(this), amount);

Expand All @@ -96,6 +109,13 @@ contract HederaVault is IERC4626 {
afterDeposit(amount);
}

/**
* @dev Mints.
*
* @param shares The amount of shares to send.
* @param to The receiver of tokens.
* @return amount The amount of tokens to receive.
*/
function mint(uint256 shares, address to) public override returns (uint256 amount) {
_mint(to, amount = previewMint(shares));

Expand All @@ -110,6 +130,14 @@ contract HederaVault is IERC4626 {
afterDeposit(amount);
}

/**
* @dev Withdraws staking token and burns shares.
*
* @param amount The amount of shares.
* @param to The staking token receiver.
* @param from The .
* @return shares The amount of shares to burn.
*/
function withdraw(uint256 amount, address to, address from) public override returns (uint256 shares) {
beforeWithdraw(amount);

Expand All @@ -125,6 +153,14 @@ contract HederaVault is IERC4626 {
asset.safeTransfer(to, amount);
}

/**
* @dev Redeems .
*
* @param shares The amount of shares.
* @param to The staking token receiver.
* @param from The .
* @return amount The amount of shares to burn.
*/
function redeem(uint256 shares, address to, address from) public override returns (uint256 amount) {
require((amount = previewRedeem(shares)) != 0, "ZERO_ASSETS");

Expand All @@ -141,17 +177,28 @@ contract HederaVault is IERC4626 {
INTERNAL HOOKS LOGIC
//////////////////////////////////////////////////////////////*/

/**
* @dev Updates user state according to withdraw inputs.
*
* @param amount The amount of shares.
*/
function beforeWithdraw(uint256 amount) internal {
// claimAllReward(0);
userContribution[msg.sender].num_shares -= amount;
totalTokens -= amount;
}

/**
* @dev Updates user state according to withdraw inputs.
*
* @param amount The amount of shares.
*/
function afterDeposit(uint256 amount) internal {
if (!userContribution[msg.sender].exist) {
for (uint i; i < tokenAddress.length; i++) {
address token = tokenAddress[i];
userContribution[msg.sender].lastClaimedAmountT[token] = rewardsAddress[token].amount;
SafeHTS.safeAssociateToken(token, msg.sender);
}
userContribution[msg.sender].num_shares = amount;
userContribution[msg.sender].exist = true;
Expand Down Expand Up @@ -223,15 +270,18 @@ contract HederaVault is IERC4626 {
REWARDS LOGIC
//////////////////////////////////////////////////////////////*/

function addReward(address _token, uint _amount) internal {
function addReward(address _token, uint _amount) public payable {
require(_amount != 0, "please provide amount");
require(totalTokens != 0, "no token staked yet");
require(msg.sender == owner, "Only owner");

uint perShareRewards;
perShareRewards = _amount.mulDivDown(1, totalTokens);
if (!rewardsAddress[_token].exist) {
tokenAddress.push(_token);
rewardsAddress[_token].exist = true;
rewardsAddress[_token].amount = perShareRewards;
SafeHTS.safeAssociateToken(_token, address(this));
ERC20(_token).safeTransferFrom(address(msg.sender), address(this), _amount);
} else {
rewardsAddress[_token].amount += perShareRewards;
Expand Down
1 change: 1 addition & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@openzeppelin/hardhat-upgrades";
import "@nomicfoundation/hardhat-chai-matchers";

import * as dotenv from "dotenv";

Expand Down
12 changes: 6 additions & 6 deletions scripts/deployVault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,35 @@ async function main() {
let client = Client.forTestnet();

const operatorPrKey = PrivateKey.fromStringECDSA(process.env.PRIVATE_KEY || '');
const operatorAccountId = AccountId.fromString(process.env.OPERATOR_ID || '');
const operatorAccountId = AccountId.fromString(process.env.ACCOUNT_ID || '');

client.setOperator(
operatorAccountId,
operatorPrKey
);

const createERC4626 = await createFungibleToken(
const stakingToken = await createFungibleToken(
"ERC4626 on Hedera",
"HERC4626",
process.env.OPERATOR_ID,
process.env.ACCOUNT_ID,
operatorPrKey.publicKey,
client,
operatorPrKey
);

const stakingTokenAddress = "0x" + createERC4626!.toSolidityAddress();
const stakingTokenAddress = "0x" + stakingToken!.toSolidityAddress();

const HederaVault = await ethers.getContractFactory("HederaVault");
const hederaVault = await HederaVault.deploy(
stakingTokenAddress,
"TST",
"TST",
{ from: deployer.address, value: ethers.parseUnits("10", 18) }
{ from: deployer.address, gasLimit: 3000000, value: ethers.parseUnits("12", 18) }
);
console.log("Hash ", hederaVault.deploymentTransaction()?.hash);
await hederaVault.waitForDeployment();

console.log(await hederaVault.getAddress());
console.log("Vault deployed with address: ", await hederaVault.getAddress());
}

main().catch((error) => {
Expand Down
6 changes: 4 additions & 2 deletions scripts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export async function addToken(
client: Client
) {
let contractFunctionParameters = new ContractFunctionParameters()
.addAddress(tokenId.toSolidityAddress())
.addAddress(tokenId)
.addUint256(amount * 1e8);

const notifyRewardTx = await new ContractExecuteTransaction()
Expand Down Expand Up @@ -153,5 +153,7 @@ module.exports = {
getClient,
createAccount,
mintToken,
TokenTransfer
TokenTransfer,
TokenBalance,
addToken,
}
Loading