forked from yearn/tokenized-strategy-foundry-mix
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #79 from term-finance/votes-wrapper
term finance vault wrapped votes token
- Loading branch information
Showing
3 changed files
with
128 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: "[sepolia-deploy] deploy vault wrapped votes" | ||
on: | ||
workflow_dispatch: | ||
inputs: | ||
vaultToken: | ||
description: 'Vault token address' | ||
required: true | ||
default: '0x' | ||
wrappedTokenName: | ||
description: 'Wrapped Votes Token name' | ||
required: true | ||
default: '0x' | ||
wrappedTokenSymbol: | ||
description: 'Wrapped Votes Token Symbol' | ||
required: true | ||
default: '0x' | ||
|
||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
environment: | ||
name: sepolia | ||
url: https://term-finance.github.io/yearn-v3-term-vault/ | ||
steps: | ||
- uses: actions/checkout@master | ||
with: | ||
fetch-depth: 0 | ||
submodules: recursive | ||
- uses: foundry-rs/foundry-toolchain@v1 | ||
- run: forge install | ||
- run: forge build | ||
- run: forge tree | ||
- run: forge script script/TermFinanceVaultWrappedVotesToken.s.sol:DeployTermFinanceVaultWrappedVotesToken --rpc-url $RPC_URL --broadcast --verify --verbosity 4 | ||
env: | ||
RPC_URL: ${{ secrets.RPC_URL }} | ||
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} | ||
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }} | ||
VAULT_TOKEN: ${{ github.event.inputs.vaultToken }} | ||
WRAPPED_TOKEN_NAME: ${{ github.event.inputs.wrappedTokenName }} | ||
WRAPPED_TOKEN_SYMBOL: ${{ github.event.inputs.wrappedTokenSymbol }} |
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,31 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.18; | ||
|
||
import "forge-std/Script.sol"; | ||
import "../src/util/TermFinanceVaultWrappedVotesToken.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
contract DeployTermFinanceVaultWrappedVotesToken is Script { | ||
function run() external { | ||
uint256 deployerPK = vm.envUint("PRIVATE_KEY"); | ||
|
||
// Set up the RPC URL (optional if you're using the default foundry config) | ||
string memory rpcUrl = vm.envString("RPC_URL"); | ||
|
||
vm.startBroadcast(deployerPK); | ||
|
||
// Retrieve environment variables | ||
address vaultToken = vm.envAddress("VAULT_TOKEN"); | ||
string memory name = vm.envString("WRAPPED_TOKEN_NAME"); | ||
string memory symbol = vm.envString("WRAPPED_TOKEN_SYMBOL"); | ||
|
||
TermFinanceVaultWrappedVotesToken wrappedToken = new TermFinanceVaultWrappedVotesToken( | ||
IERC20(vaultToken), | ||
name, | ||
symbol | ||
); | ||
console.log("deployed wrapped token contract to"); | ||
console.log(address(wrappedToken)); | ||
vm.stopBroadcast(); | ||
} | ||
} |
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,57 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; | ||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
|
||
contract TermFinanceVaultWrappedVotesToken is ERC20Votes, Ownable { | ||
IERC20 public immutable underlyingToken; | ||
|
||
// Mapping to track the amount of underlying tokens deposited by each account | ||
mapping(address => uint256) public deposits; | ||
|
||
event Wrapped(address indexed user, uint256 amount); | ||
event Unwrapped(address indexed user, uint256 amount); | ||
|
||
constructor( | ||
IERC20 _underlyingToken, | ||
string memory name, | ||
string memory symbol | ||
) ERC20(name, symbol) ERC20Permit(name) { | ||
underlyingToken = _underlyingToken; | ||
} | ||
|
||
// Function to wrap the underlying tokens and mint ERC20Votes tokens | ||
function wrap(uint256 amount) external { | ||
require(amount > 0, "Amount must be greater than zero"); | ||
|
||
// Transfer the underlying tokens from the user to the contract | ||
require(underlyingToken.transferFrom(msg.sender, address(this), amount), "Transfer failed"); | ||
|
||
// Track the deposit | ||
deposits[msg.sender] += amount; | ||
|
||
// Mint ERC20Votes tokens to the user | ||
_mint(msg.sender, amount); | ||
|
||
emit Wrapped(msg.sender, amount); | ||
} | ||
|
||
// Function to unwrap the ERC20Votes tokens and retrieve the underlying tokens | ||
function unwrap(uint256 amount) external { | ||
require(amount > 0, "Amount must be greater than zero"); | ||
require(balanceOf(msg.sender) >= amount, "Insufficient balance"); | ||
|
||
// Burn the ERC20Votes tokens | ||
_burn(msg.sender, amount); | ||
|
||
// Reduce the deposit record | ||
deposits[msg.sender] -= amount; | ||
|
||
// Transfer the underlying tokens back to the user | ||
require(underlyingToken.transfer(msg.sender, amount), "Transfer failed"); | ||
|
||
emit Unwrapped(msg.sender, amount); | ||
} | ||
} |