Explorando o Contrato Inteligente de Gerenciamento de Liquidez: Desmembramento das Funções
No mundo das finanças descentralizadas (DeFi), contratos inteligentes desempenham um papel fundamental ao permitir várias atividades financeiras. Um contrato desse tipo é o contrato inteligente Liquidity
, projetado para gerenciar a provisão de liquidez e a troca de tokens entre dois tokens ERC-20, DOGE e USDT. Neste artigo, vamos analisar as funções-chave deste contrato para compreender seu funcionamento interno e as funcionalidades que ele oferece.
Foto de Jievani Weerasinghe no Unsplash
Função setAddresses(address _DOGE, address _usdt)
A função setAddresses()
é usada pelo proprietário do contrato para definir os endereços dos tokens DOGE e USDT. Este passo é vital, pois estabelece a conexão entre o contrato e os tokens que ele irá gerenciar. As interfaces IERC20
são utilizadas para criar instâncias dos contratos de token.
function setAddresses(address _DOGE, address _usdt) public onlyOwner {
DOGE = IERC20(_DOGE);
USDT = IERC20(_usdt);
}
Função getReserves()
A função getReserves()
permite que terceiros externos obtenham as reservas atuais dos tokens DOGE e USDT dentro do contrato. Essas reservas são cruciais para diversos cálculos ao longo das operações do contrato, garantindo uma provisão de liquidez precisa e troca de tokens.
function getReserves()
public
view
returns (uint256 _reserve1, uint256 _reserve2)
{
_reserve1 = reserve1;
_reserve2 = reserve2;
}
Função quote(uint256 amountA, uint256 reserveA, uint256 reserveB)
A função quote()
é usada internamente para calcular a cotação para a troca de tokens. Dado o valor desejado amountA
para a troca e as reservas atuais dos tokens A (reserveA
) e B (reserveB
), esta função calcula o montante correspondente de token B que será recebido após a troca. Ela garante que haja liquidez suficiente para que a troca ocorra.
function quote(
uint256 amountA,
uint256 reserveA,
uint256 reserveB
) internal pure returns (uint256) {
require(amountA > 0, "UniswapV2Library: MONTANTE_INSUFICIENTE");
require(
reserveA > 0 && reserveB > 0,
"UniswapV2Library: LIQUIDEZ_INSUFICIENTE"
);
uint256 amountB = amountA.mul(reserveB) / reserveA;
return amountB;
}
Função _addLiquidity(uint256 _DOGEQuantity, uint256 _USDTQuantity)
A função _addLiquidity()
calcula os montantes ideais de DOGE e USDT a serem adicionadas para o fornecimento de liquidez. Ela leva em consideração as reservas e saldos atuais, bem como os montantes desejados de ambos os tokens. Os montantes calculados garantem que o pool de liquidez permaneça equilibrado e eficiente.
function _addLiquidity(
uint256 _DOGEQuantity,
uint256 _USDTQuantity
) internal view returns (uint256 amountA, uint256 amountB) {
require(
_DOGEQuantity != 0 && _USDTQuantity != 0,
"montante do token não pode ser zero"
);
(uint256 reserveA, uint256 reserveB) = getReserves();
if (reserveA == 0 && reserveB == 0) {
(amountA, amountB) = (_DOGEQuantity, _USDTQuantity);
} else {
uint256 amount2Optimal = quote(_DOGEQuantity, reserveA, reserveB);
if (amount2Optimal <= _USDTQuantity) {
(amountA, amountB) = (_DOGEQuantity, amount2Optimal);
} else {
uint256 amountAOptimal = quote(
_USDTQuantity,
reserveB,
reserveA
);
assert(amountAOptimal <= _DOGEQuantity);
(amountA, amountB) = (amountAOptimal, _USDTQuantity);
}
}
}
Função addLiquidity(uint256 amountDOGE, uint256 amountUSDT, address to)
A função addLiquidity()
permite que os usuários depositem tokens DOGE e USDT para fornecer liquidez. Ela calcula os montantes ideais de tokens a serem adicionados usando a função _addLiquidity()
, transfere os tokens do endereço do usuário para o contrato e emite tokens LP que representam a liquidez fornecida.
function addLiquidity(
uint256 amountDOGE,
uint256 amountUSDT,
address to
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity) {
(amountA, amountB) = _addLiquidity(amountDOGE, amountUSDT);
DOGE.safeTransferFrom(msg.sender, address(this), amountA);
USDT.safeTransferFrom(msg.sender, address(this), amountB);
liquidity = mintLPToken(to);
}
Função mintLPToken(address to)
A função mintLPToken()
calcula o montante de tokens LP a serem emitidos quando a liquidez é adicionada. Ela garante que o montante inicial de liquidez atenda aos requisitos mínimos e distribui tokens LP proporcionalmente aos usuários.
function mintLPToken(address to) internal returns (uint256 liquidity) {
(uint256 _reserve0, uint256 _reserve1) = getReserves(); // economia de gás
uint256 balance0 = DOGE.balanceOf(address(this));
uint256 balance1 = USDT.balanceOf(address(this));
uint256 amount0 = balance0.sub(_reserve0);
uint256 amount1 = balance1.sub(_reserve1);
uint256 _totalLiquidity = totalLiquidity;
if (_totalLiquidity == 0) {
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
userLiquidity[address(0)] = MINIMUM_LIQUIDITY;
} else {
liquidity = Math.min(
amount0.mul(_totalLiquidity) / _reserve0,
amount1.mul(_totalLiquidity) / _reserve1
);
}
require(liquidity > 0, "INSUFICIENTE_LIQUIDEZ_CUNHADA");
userLiquidity[to] += liquidity;
totalLiquidity += liquidity;
reserve1 = DOGE.balanceOf(address(this));
reserve2 = USDT.balanceOf(address(this));
}
Função burn(uint256 liquidity)
A função burn()
calcula os montantes de tokens DOGE e USDT a serem devolvidos aos usuários quando a liquidez é removida. Ela determina a distribuição proporcional com base na liquidez fornecida e garante que ambos os tokens sejam devolvidos nos montantes adequados.
function burn(
uint256 liquidity
) internal returns (uint256 amount0, uint256 amount1) {
uint256 balance0 = DOGE.balanceOf(address(this));
uint256 balance1 = USDT.balanceOf(address(this));
uint256 _totalLiquidity = totalLiquidity;
amount0 = liquidity.mul(balance0) / _totalLiquidity;
amount1 = liquidity.mul(balance1) / _totalLiquidity; // a utilização dos saldos garante uma distribuição proporcional
require(
amount0 > 0 && amount1 > 0,
"LIQUIDEZ_INSUFICIENTE_QUEIMADA: Aumente o montante de liquidez"
);
totalLiquidity -= liquidity;
}
Função removeLiquidity(uint256 liquidity, address to)
A função removeLiquidity()
permite aos usuários remover a liquidez do pool. Ela calcula o montante de tokens DOGE e USDT a serem devolvidos ao usuário e transfere os tokens de acordo com isso. A liquidez do usuário é atualizada e a liquidez total e as reservas são ajustadas.
function removeLiquidity(
uint256 liquidity,
address to
) public returns (uint256 amountA, uint256 amountB) {
require(
userLiquidity[msg.sender] >= liquidity,
"LIQUIDEZ_INSUFICIENTE"
);
(amountA, amountB) = burn(liquidity);
DOGE.safeTransfer(to, amountA);
USDT.safeTransfer(to, amountB);
userLiquidity[msg.sender] -= liquidity;
reserve1 = DOGE.balanceOf(address(this));
reserve2 = USDT.balanceOf(address(this));
}
Função swapDOGEForUSDT(uint256 amountIn, address _to)
A função swapDOGEForUSDT()
facilita a troca de tokens DOGE por tokens USDT. Ela calcula o montante de tokens USDT a serem obtidos com base no montante de tokens DOGE de entrada e realiza a troca. As reservas do contrato são atualizadas adequadamente.
function swapDOGEForUSDT(uint256 amountIn, address _to) external {
require(amountIn > 0, "MONTANTE_DE_ENTRADA_INSUFICIENTE");
(uint256 reserveIn, uint256 reserveOut) = getReserves();
require(
reserveIn > 0 && reserveOut > 0,
"UniswapV2Library: LIQUIDEZ_INSUFICIENTE"
);
uint256 amountInWithFee = amountIn.mul(997);
uint256 numerator = amountInWithFee.mul(reserveOut);
uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
uint256 amountOut = numerator / denominator;
require(amountOut <= reserveOut, "UniswapV2: LIQUIDEZ_INSUFICIENTE");
DOGE.safeTransferFrom(_to, address(this), amountIn);
USDT.safeTransfer(_to, amountOut);
reserve1 = DOGE.balanceOf(address(this));
reserve2 = USDT.balanceOf(address(this));
}
Função swapUSDTForDOGE(uint256 amountIn, address _to)
A função swapUSDTForDOGE()
permite aos usuários trocar tokens USDT por tokens DOGE. Semelhante à função anterior, ela calcula o montante de tokens DOGE a serem obtidos com base no montante de tokens USDT de entrada e realiza a troca, atualizando as reservas do contrato.
function swapUSDTForDOGE(uint256 amountIn, address _to) external {
require(amountIn > 0, "MONTANTE_DE_ENTRADA_INSUFICIENTE");
(uint256 reserveOut, uint256 reserveIn) = getReserves();
require(
reserveIn > 0 && reserveOut > 0,
"UniswapV2Library: LIQUIDEZ_INSUFICIENTE"
);
uint256 amountInWithFee = amountIn.mul(997);
uint256 numerator = amountInWithFee.mul(reserveOut);
uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
uint256 amountOut = numerator / denominator;
require(amountOut <= reserveOut, "UniswapV2: LIQUIDEZ_INSUFICIENTE");
USDT.safeTransferFrom(_to, address(this), amountIn);
DOGE.safeTransfer(_to, amountOut);
reserve1 = DOGE.balanceOf(address(this));
reserve2 = USDT.balanceOf(address(this));
}
Conclusão
O contrato inteligente Liquidity
encapsula as funcionalidades necessárias para fornecer liquidez e trocar tokens dentro do ecossistema DeFi. Ao explorar o propósito e a operação de cada função, obtemos informações sobre as capacidades do contrato. É importante notar que essa explicação fornece uma compreensão de alto nível e a implementação real pode envolver considerações adicionais, como medidas de segurança e eficiência de gás. O contrato Liquidity
exemplifica o poder dos contratos inteligentes na revolução das transações financeiras na blockchain.
Pode ver o código completo AQUI.
Apoie-nos AQUI.
Muito obrigado!
Artigo escrito por Rohit Goyal. Traduzido por Marcelo Panegali.
Top comments (0)