WJU 包装代币
WJU(Wrapped JU)是JuChain原生代币JU的ERC-20包装版本。由于AMM系统需要所有代币都遵循ERC-20标准,WJU合约提供了JU代币与ERC-20代币之间的无缝转换功能,使得JU代币能够参与JAMM DEX的所有交易活动。
合约实现
基本信息
contract WJU is IWJU {
string public constant override name = "Wrapped JU";
string public constant override symbol = "WJU";
uint8 public constant override decimals = 18;
uint public override totalSupply;
mapping(address => uint) public override balanceOf;
mapping(address => mapping(address => uint)) public override allowance;
}
WJU合约完全实现了ERC-20标准,具有以下特性:
名称: "Wrapped JU"
符号: "WJU"
精度: 18位小数
1:1兑换: 1 JU = 1 WJU
核心功能
包装功能(Deposit)
用户可以通过两种方式将JU代币包装为WJU:
方式1:直接发送JU
receive() external payable {
deposit();
}
用户直接向WJU合约地址发送JU代币,合约会自动调用deposit()
函数。
方式2:调用deposit函数
function deposit() public payable override {
balanceOf[msg.sender] += msg.value;
totalSupply += msg.value;
emit Deposit(msg.sender, msg.value);
}
包装过程:
用户发送JU代币到合约
合约增加用户的WJU余额
增加WJU总供应量
触发Deposit事件
解包装功能(Withdraw)
用户可以将WJU代币换回JU代币:
function withdraw(uint amount) public override {
require(balanceOf[msg.sender] >= amount);
balanceOf[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
emit Withdrawal(msg.sender, amount);
}
解包装过程:
检查用户WJU余额是否足够
减少用户的WJU余额
向用户转账相应数量的JU代币
触发Withdrawal事件
ERC-20标准实现
转账功能
function transfer(address to, uint amount) public override returns (bool) {
require(balanceOf[msg.sender] >= amount, "WJU: INSUFFICIENT_BALANCE");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
授权转账功能
function transferFrom(
address from,
address to,
uint amount
) public override returns (bool) {
require(
allowance[from][msg.sender] >= amount,
"WJU: INSUFFICIENT_ALLOWANCE"
);
require(balanceOf[from] >= amount, "WJU: INSUFFICIENT_BALANCE");
allowance[from][msg.sender] -= amount;
balanceOf[from] -= amount;
balanceOf[to] += amount;
emit Transfer(from, to, amount);
return true;
}
授权功能
function approve(
address spender,
uint amount
) public override returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
事件系统
Deposit事件
event Deposit(address indexed sender, uint amount);
记录JU代币包装为WJU的操作。
Withdrawal事件
event Withdrawal(address indexed sender, uint amount);
记录WJU代币解包装为JU的操作。
ERC-20标准事件
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
在JAMM DEX中的应用
Router集成
JAMMRouter合约与WJU深度集成,提供便捷的JU代币交易功能:
address public immutable override WJU;
constructor(address _factory, address _WJU) {
factory = _factory;
WJU = _WJU;
}
receive() external payable {
assert(msg.sender == WJU); // 只接受来自WJU合约的ETH
}
JU代币交易
用JU购买代币
function swapExactETHForTokens(
uint amountOutMin,
address[] calldata path,
uint24[] calldata fees,
address to,
address referrer,
uint deadline
) external payable virtual override ensure(deadline) returns (uint[] memory amounts) {
require(path[0] == WJU, "JAMMRouter: INVALID_PATH");
amounts = JAMMLibrary.getAmountsOut(factory, msg.value, path, fees);
require(
amounts[amounts.length - 1] >= amountOutMin,
"JAMMRouter: INSUFFICIENT_OUTPUT_AMOUNT"
);
IWJU(WJU).deposit{value: amounts[0]}();
assert(
IWJU(WJU).transfer(
JAMMLibrary.pairFor(factory, path[0], path[1], fees[0]),
amounts[0]
)
);
_swap(amounts, path, fees, to, referrer);
}
交易流程:
用户发送JU代币
Router将JU包装为WJU
将WJU转入交易对
执行交换逻辑
用户收到目标代币
卖出代币换JU
function swapExactTokensForETH(
uint amountIn,
uint amountOutMin,
address[] calldata path,
uint24[] calldata fees,
address to,
address referrer,
uint deadline
) external virtual override ensure(deadline) returns (uint[] memory amounts) {
require(path[path.length - 1] == WJU, "JAMMRouter: INVALID_PATH");
amounts = JAMMLibrary.getAmountsOut(factory, amountIn, path, fees);
require(
amounts[amounts.length - 1] >= amountOutMin,
"JAMMRouter: INSUFFICIENT_OUTPUT_AMOUNT"
);
TransferHelper.safeTransferFrom(
path[0],
msg.sender,
JAMMLibrary.pairFor(factory, path[0], path[1], fees[0]),
amounts[0]
);
_swap(amounts, path, fees, address(this), referrer);
IWJU(WJU).withdraw(amounts[amounts.length - 1]);
TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
}
交易流程:
用户授权并转入代币
执行交换得到WJU
Router将WJU解包装为JU
向用户转账JU代币
流动性管理
添加JU流动性
function addLiquidityETH(
address token,
uint24 fee,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable virtual override ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
(amountToken, amountETH) = _addLiquidity(
token,
WJU,
fee,
amountTokenDesired,
msg.value,
amountTokenMin,
amountETHMin
);
address pair = JAMMLibrary.pairFor(factory, token, WJU, fee);
TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
IWJU(WJU).deposit{value: amountETH}();
assert(IWJU(WJU).transfer(pair, amountETH));
liquidity = IJAMMPair(pair).mint(to);
// 退还多余的JU
if (msg.value > amountETH)
TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
}
移除JU流动性
function removeLiquidityETH(
address token,
uint24 fee,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) {
(amountToken, amountETH) = removeLiquidity(
token,
WJU,
fee,
liquidity,
amountTokenMin,
amountETHMin,
address(this),
deadline
);
TransferHelper.safeTransfer(token, to, amountToken);
IWJU(WJU).withdraw(amountETH);
TransferHelper.safeTransferETH(to, amountETH);
}
使用示例
基本包装/解包装
const wju = new ethers.Contract(WJU_ADDRESS, wjuABI, signer);
// 包装JU为WJU
const depositTx = await wju.deposit({ value: ethers.utils.parseEther("1.0") });
await depositTx.wait();
// 或者直接发送JU到WJU合约地址
const directTx = await signer.sendTransaction({
to: WJU_ADDRESS,
value: ethers.utils.parseEther("1.0")
});
await directTx.wait();
// 解包装WJU为JU
const withdrawTx = await wju.withdraw(ethers.utils.parseEther("1.0"));
await withdrawTx.wait();
查询余额
// 查询WJU余额
const wjuBalance = await wju.balanceOf(userAddress);
console.log("WJU余额:", ethers.utils.formatEther(wjuBalance));
// 查询JU余额
const juBalance = await provider.getBalance(userAddress);
console.log("JU余额:", ethers.utils.formatEther(juBalance));
监听事件
// 监听包装事件
wju.on("Deposit", (sender, amount, event) => {
console.log(`${sender} 包装了 ${ethers.utils.formatEther(amount)} JU`);
});
// 监听解包装事件
wju.on("Withdrawal", (sender, amount, event) => {
console.log(`${sender} 解包装了 ${ethers.utils.formatEther(amount)} WJU`);
});
安全考虑
合约安全
简单设计: WJU合约逻辑简单,减少了安全风险
无管理员: 合约没有管理员功能,完全去中心化
1:1兑换: 严格的1:1兑换比例,无法被操纵
使用安全
余额检查: 所有操作都会检查余额是否足够
溢出保护: 使用Solidity 0.8.21的内置溢出保护
事件记录: 所有操作都有相应的事件记录
Last updated