Recentemente, tenho revisado meus conhecimentos em Solidity e consolidando alguns detalhes, e escrevendo um "WTF Introdução Simples à Solidity" para ajudar os novatos (os programadores experientes podem procurar outro tutorial), com atualizações semanais de 1 a 3 aulas.
Twitter: @0xAA_Science
Comunidade: Discord | Grupo do WhatsApp | Website wtf.academy
Todo o código e os tutoriais estão disponíveis no Github: github.com/AmazingAng/WTF-Solidity
Nesta aula, vamos falar sobre termos de titularidade de tokens e escrever um contrato de token ERC20 para liberação linear. O código foi simplificado do contrato VestingWallet
da OpenZeppelin
.
No mundo financeiro tradicional, algumas empresas oferecem ações para funcionários e gestores. No entanto, a liberação de grandes quantidades de ações ao mesmo tempo pode gerar uma pressão de venda a curto prazo, afetando o preço das ações. Portanto, as empresas costumam introduzir um período de titularidade para retardar a posse dos ativos prometidos. Da mesma forma, no ecossistema blockchain, empresas iniciantes do Web3 distribuem tokens para suas equipes e também vendem tokens a baixo custo para investidores e em rodadas privadas. Se eles levarem esses tokens de baixo custo para exchanges simultaneamente para obter lucro, o preço do token será impactado, e os investidores diretos se tornarão compradores. Portanto, as equipes de projeto geralmente estabelecem termos de titularidade de tokens (token vesting), liberando gradualmente os tokens durante o período de titularidade para reduzir a pressão de venda e impedir que as equipes e os investidores obtenham lucro muito cedo.
A liberação linear significa que os tokens são liberados de maneira uniforme durante o período de titularidade. Por exemplo, se um investidor privado detém 365.000 tokens ICU
, com um período de titularidade de 1 ano (365 dias), serão liberados 1.000 tokens por dia.
A seguir, vamos escrever um contrato TokenVesting
que bloqueia e libera tokens ERC20 de forma linear. A lógica é simples:
- O projeto especifica o beneficiário, o início do período de titularidade e o beneficiário.
- O projeto transfere os tokens ERC20 bloqueados para o contrato
TokenVesting
. - O beneficiário pode chamar a função
release
para retirar os tokens liberados do contrato.
Existem 1 evento no contrato de liberação linear.
ERC20Released
: Evento de liberação, acionado quando o beneficiário retira os tokens liberados.
contract TokenVesting {
// Eventos
event ERC20Released(address indexed token, uint256 amount); // Evento acionado ao retirar os tokens
Existem 4 variáveis de estado no contrato de liberação linear.
beneficiary
: Endereço do beneficiário.start
: Timestamp de início do período de titularidade.duration
: Duração do período de titularidade em segundos.erc20Released
: Mapeamento de endereço de token para quantidade liberada, registrando a quantidade de tokens liberada ao beneficiário.
// Variáveis de Estado
mapping(address => uint256) public erc20Released; // Mapeamento de endereço de token para quantidade liberada
address public immutable beneficiary; // Endereço do beneficiário
uint256 public immutable start; // Timestamp de início
uint256 public immutable duration; // Duração
Existem 3 funções no contrato de liberação linear.
- Construtor: Inicializa o endereço do beneficiário, a duração do período de titularidade e o timestamp de início. Os parâmetros são o endereço do beneficiário
beneficiaryAddress
e a duração do períododurationSeconds
. Para facilitar, o timestamp de início é o timestamp de bloco atualblock.timestamp
. release()
: Função para retirar tokens, transfere os tokens liberados para o beneficiário. Chama a funçãovestedAmount()
para calcular a quantidade de tokens liberados, emite o eventoERC20Released
e, em seguida, transfere os tokens para o beneficiário. O parâmetro é o endereço do tokentoken
.vestedAmount()
: Calcula a quantidade de tokens liberados com base na fórmula de liberação linear. Os desenvolvedores podem personalizar esse cálculo modificando a função. Os parâmetros são o endereço do tokentoken
e o timestamp de consultatimestamp
.
/**
* @dev Inicializa o endereço do beneficiário, o período de liberação (em segundos) e o timestamp de início (timestamp atual do bloco).
*/
constructor(
address beneficiaryAddress,
uint256 durationSeconds
) {
require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address");
beneficiary = beneficiaryAddress;
start = block.timestamp;
duration = durationSeconds;
}
/**
* @dev O beneficiário retira os tokens liberados.
* Chama a função vestedAmount() para calcular a quantidade de tokens a serem retirados e transfere esses tokens ao beneficiário.
* Emite o evento {ERC20Released}.
*/
function release(address token) public {
// Calcula a quantidade de tokens a serem retirados usando a função vestedAmount()
uint256 releasable = vestedAmount(token, uint256(block.timestamp)) - erc20Released[token];
// Atualiza a quantidade de tokens liberados
erc20Released[token] += releasable;
// Transfere os tokens para o beneficiário
emit ERC20Released(token, releasable);
IERC20(token).transfer(beneficiary, releasable);
}
/**
* @dev Calcula a quantidade de tokens liberados com base na fórmula de liberação linear. Os desenvolvedores podem personalizar essa função.
* @param token: Endereço do token
* @param timestamp: Timestamp de consulta
*/
function vestedAmount(address token, uint256 timestamp) public view returns (uint256) {
// Calcula o total de tokens recebidos pelo contrato (saldo atual + liberados)
uint256 totalAllocation = IERC20(token).balanceOf(address(this)) + erc20Released[token];
// Calcula a quantidade de tokens liberados com base na fórmula de liberação linear
if (timestamp < start) {
return 0;
} else if (timestamp > start + duration) {
return totalAllocation;
} else {
return (totalAllocation * (timestamp - start)) / duration;
}
}
1. Implemente o contrato ERC20
da Aula 31 e crie 10000
tokens para si mesmo.
2. Implemente o contrato TokenVesting
de liberação linear, com você mesmo como beneficiário e um período de titularidade de 100
segundos.
O desbloqueio em massa de tokens pode gerar uma grande pressão de venda nos preços, enquanto os termos de titularidade de tokens podem reduzir essa pressão e evitar que as equipes e investidores saiam muito cedo. Nesta aula, apresentamos os termos de titularidade de tokens e escrevemos um contrato para liberação linear de tokens ERC20.