WJU 合约
WJU(Wrapped JU)是JuChain原生代币JU的ERC-20包装版本。作为JAMM DEX生态系统的重要组成部分,WJU使得JU代币能够无缝参与所有DeFi活动。WJU合约设计简洁、安全可靠,提供1:1的双向兑换功能。
合约基本信息
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;
}
代币信息:
名称: "Wrapped JU"
符号: "WJU"
精度: 18位小数(与JU相同)
兑换比例: 1 JU = 1 WJU
核心功能
包装功能(Deposit)
直接发送JU
receive() external payable {
deposit();
}
用户可以直接向WJU合约地址发送JU代币,合约会自动调用deposit()
函数进行包装。
主动调用包装
function deposit() public payable override {
balanceOf[msg.sender] += msg.value;
totalSupply += msg.value;
emit Deposit(msg.sender, msg.value);
}
包装流程:
接收用户发送的JU代币
增加用户的WJU余额
增加WJU总供应量
发射Deposit事件
特点:
1:1兑换比例
即时生效
无手续费
无最小/最大限制
解包装功能(Withdraw)
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事件
安全检查:
余额充足性检查
使用Solidity 0.8.21的内置溢出保护
安全的ETH转账
ERC-20标准实现
授权功能
function approve(
address spender,
uint amount
) public override returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
转账功能
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;
}
双重检查:
授权额度检查
余额充足性检查
自动减少授权额度
事件系统
Deposit事件
event Deposit(address indexed sender, uint amount);
记录JU代币包装为WJU的操作,包含:
sender
: 包装操作的发起者amount
: 包装的数量
Withdrawal事件
event Withdrawal(address indexed sender, uint amount);
记录WJU代币解包装为JU的操作,包含:
sender
: 解包装操作的发起者amount
: 解包装的数量
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功能:
address public immutable override WJU;
constructor(address _factory, address _WJU) {
factory = _factory;
WJU = _WJU;
}
receive() external payable {
assert(msg.sender == WJU); // 只接受来自WJU合约的ETH
}
自动包装/解包装
Router在处理JU相关交易时会自动进行包装/解包装:
交换中的自动包装
// 用户调用swapExactETHForTokens时的内部流程
function swapExactETHForTokens(...) external payable {
// 1. 将接收到的JU包装为WJU
IWJU(WJU).deposit{value: amounts[0]}();
// 2. 将WJU转入交易对
assert(IWJU(WJU).transfer(pairAddress, amounts[0]));
// 3. 执行交换
_swap(amounts, path, fees, to, referrer);
}
交换中的自动解包装
// 用户调用swapExactTokensForETH时的内部流程
function swapExactTokensForETH(...) external {
// 1. 执行交换得到WJU
_swap(amounts, path, fees, address(this), referrer);
// 2. 将WJU解包装为JU
IWJU(WJU).withdraw(amounts[amounts.length - 1]);
// 3. 将JU转给用户
TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
}
使用示例
基本包装/解包装操作
const wju = new ethers.Contract(WJU_ADDRESS, wjuABI, signer);
// 方式1: 调用deposit函数包装
const depositTx = await wju.deposit({
value: ethers.utils.parseEther("1.0")
});
await depositTx.wait();
console.log("包装成功");
// 方式2: 直接发送JU到WJU合约
const directTx = await signer.sendTransaction({
to: WJU_ADDRESS,
value: ethers.utils.parseEther("1.0")
});
await directTx.wait();
console.log("直接包装成功");
// 解包装WJU为JU
const withdrawTx = await wju.withdraw(ethers.utils.parseEther("1.0"));
await withdrawTx.wait();
console.log("解包装成功");
余额查询
// 查询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总供应量
const totalSupply = await wju.totalSupply();
console.log("WJU总供应量:", ethers.utils.formatEther(totalSupply));
ERC-20操作
// 授权
const approveTx = await wju.approve(spenderAddress, ethers.utils.parseEther("10"));
await approveTx.wait();
// 转账
const transferTx = await wju.transfer(recipientAddress, ethers.utils.parseEther("1"));
await transferTx.wait();
// 查询授权额度
const allowance = await wju.allowance(ownerAddress, spenderAddress);
console.log("授权额度:", ethers.utils.formatEther(allowance));
事件监听
// 监听包装事件
wju.on("Deposit", (sender, amount) => {
console.log(`${sender} 包装了 ${ethers.utils.formatEther(amount)} JU`);
});
// 监听解包装事件
wju.on("Withdrawal", (sender, amount) => {
console.log(`${sender} 解包装了 ${ethers.utils.formatEther(amount)} WJU`);
});
// 监听转账事件
wju.on("Transfer", (from, to, value) => {
console.log(`转账: ${from} -> ${to}, 数量: ${ethers.utils.formatEther(value)}`);
});
批量操作
// 批量包装多个用户的JU
async function batchWrap(users, amounts) {
const promises = users.map((user, index) => {
const userSigner = new ethers.Wallet(user.privateKey, provider);
const userWJU = wju.connect(userSigner);
return userWJU.deposit({ value: amounts[index] });
});
const results = await Promise.all(promises);
console.log("批量包装完成");
return results;
}
Last updated