前言本文主要实现代币锁合约的开发、测试、部署全流程,以及对该合约使用场景分析介绍;代币锁定义:将一定数量的代币在一段时间内限制其交易和转移的行为,主要目标是激励长期承诺,阻止早期投资者或团队成员迅速出售代币获利,然后退出项目。功能时间锁定:代币在特定的时间段内无法转移或使用。这是最常
本文主要实现代币锁合约的开发、测试、部署全流程,以及对该合约使用场景分析介绍;
代币锁
定义:将一定数量的代币在一段时间内限制其交易和转移的行为,主要目标是激励长期承诺,阻止早期投资者或团队成员迅速出售代币获利,然后退出项目。
功能
- 时间锁定:代币在特定的时间段内无法转移或使用。这是最常见的锁仓方式,用于限制代币的流通,以防止投资者过早地出售或交易代币,从而维护代币的稳定性和价值。
- 数量锁定:将一定数量的代币存储在一个地址中,要求在一定的时间段内保持该数量的锁定状态。这种锁仓机制可以用于项目的众筹阶段或私募轮等,确保项目团队或投资者在一段时间内持有一定数量的代币,以体现其对项目的承诺和信心。
- 条件锁定:根据特定的条件来触发或解除锁仓状态。这种锁仓机制通常用于智能合约中,通过设定一些条件,如特定日期、价格或事件等,来限制或释放数字资产的流通。条件锁定可以用于项目的预售期、团队解锁、投资者奖励等,以实现更灵活的资产管理和治理。
解锁的方式
- 线性解锁:代币逐渐按时间线性解锁,比如每月解锁一定比例。
- 阶段性解锁:代币在特定时间点或达到特定里程碑时解锁。
- 一次性解锁:所有锁定的代币在特定时间点一次性全部解锁。
合约说明:主要实现锁定代币和释放代币功能
// SPDX-License-Identifier: MIT
// wtf.academy
pragma solidity ^0.8.22;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "hardhat/console.sol";
/**
* @dev ERC20代币时间锁合约。受益人在锁仓一段时间后才能取出代币。
*/
contract TokenLocker {
// 事件
event TokenLockStart(address indexed beneficiary, address indexed token, uint256 startTime, uint256 lockTime);
event Release(address indexed beneficiary, address indexed token, uint256 releaseTime, uint256 amount);
// 被锁仓的ERC20代币合约
IERC20 public immutable token;
// 受益人地址
address public immutable beneficiary;
// 锁仓时间(秒)
uint256 public immutable lockTime;
// 锁仓起始时间戳(秒)
uint256 public immutable startTime;
/**
* @dev 部署时间锁合约,初始化代币合约地址,受益人地址和锁仓时间。
* @param token_: 被锁仓的ERC20代币合约
* @param beneficiary_: 受益人地址
* @param lockTime_: 锁仓时间(秒)
*/
constructor(
IERC20 token_,
address beneficiary_,
uint256 lockTime_
) {
require(lockTime_ > 0, "TokenLock: lock time should greater than 0");
token = token_;
beneficiary = beneficiary_;
lockTime = lockTime_;
startTime = block.timestamp;
emit TokenLockStart(beneficiary_, address(token_), block.timestamp, lockTime_);
}
/**
* @dev 在锁仓时间过后,将代币释放给受益人。
*/
function release() public {
require(block.timestamp >= startTime+lockTime, "TokenLock: current time is before release time");
uint256 amount = token.balanceOf(address(this));
require(amount > 0, "TokenLock: no tokens to release");
token.transfer(beneficiary, amount);
emit Release(msg.sender, address(token), block.timestamp, amount);
}
}
# 编译指令
# npx hardhat compile
测试说明:测试采用获取当前代币时间戳来,从而实现对时间到期的模拟
const {ethers,getNamedAccounts,deployments} = require("hardhat");
const { assert,expect } = require("chai");
describe("代币锁",function(){
let token;
let TokenLocker;
let addr1;
let addr2;
let firstAccount;
let secondAccount;
beforeEach(async function(){
await deployments.fixture(["token","TokenLocker"]);
[addr1,addr2]=await ethers.getSigners();
firstAccount=(await getNamedAccounts()).firstAccount;
secondAccount=(await getNamedAccounts()).secondAccount;
//代币合约
const tokenDeployment = await deployments.get("MyToken");
token = await ethers.getContractAt("MyToken",tokenDeployment.address);//已经部署的合约交互
//代币锁合约
const TokenLockerDeployment = await deployments.get("TokenLocker");
TokenLocker = await ethers.getContractAt("TokenLocker",TokenLockerDeployment.address);//已经部署的合约交互
});
describe("代币锁合约",function(){
it("代币锁合约测试",async function(){
// console.log(await TokenLocker.release())
//转入代币合约
await token.transfer(TokenLocker.address,ethers.utils.parseEther("20"));
let balanceOf=await token.balanceOf(TokenLocker.address)
console.log("合约中的代币金额",`${ethers.utils.formatEther(balanceOf)} ETH`)
//获取当前时间
const currentTime = await ethers.provider.getBlock("latest").then(block => block.timestamp);
console.log(currentTime)
// 模拟时间流逝,增加 时间(200 秒)
await ethers.provider.send("evm_increaseTime", [200]);
await ethers.provider.send("evm_mine", []); // 挖一个区块,使时间生效
console.log(await ethers.provider.getBlock("latest").then(block => block.timestamp))
//时间到释放代币
await TokenLocker.release();//
console.log("释放后的合约里的代币",`${ethers.utils.formatEther(await token.balanceOf(TokenLocker.address))} ETH`)
})
})
})
# 测试指令
# npx hardhat test ./test/xxx.js
module.exports = async function ({getNamedAccounts,deployments}) {
const firstAccount= (await getNamedAccounts()).firstAccount;
const secondAccount= (await getNamedAccounts()).secondAccount;
const {deploy,log}=deployments;
//获取token合约地址
const MyToken=await deployments.get("MyToken");
const TokenAddress = MyToken.address;
console.log(TokenAddress)
const TokenLocker=await deploy("TokenLocker",{
from:firstAccount,
args: [TokenAddress,firstAccount,180],//参数 参数 被锁仓的ERC20代币合约、受益人地址、锁仓时间
log: true,
})
console.log('TokenLocker合约地址',TokenLocker.address)
}
module.exports.tags = ["all", "TokenLocker"];
# 部署指令
# npx hardhat deploy
以上就是代币锁合约开发、测试、部署全流程,以及对代币锁的使用场景的分析。注意
:测试中主要通过获取当前区块时间戳的方式,从而实现过期时间的模拟测试;
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!