# LP质押奖励合约 目前 LP 质押奖励合约部署币安智能链测试网,打开 [Binance Smart Chain Testnet RPC and Chain settings | Chainlist](https://chainlist.org/zh/chain/97) 可将测试网络添加到 MetaMask 钱包。用户可以把 PancakeSwap 的 **tBNB-SIE LP** 代币或者 **tBNB-GAS LP** 代币质押到合约,系统会按照每个人的质押权重计算 **SIE** 代币奖励。合约地址列表如下: * SIE 合约地址:`0xe29d4e3ca2dc5e91729c508fce5a3e20ed2c34ea` * GAS 合约地址:`0x22d263c324c4613f09c7a8a9f8fa0d3cdc03f0d1` * PancakeSwap tBNB-SIE LP(在BNB/SIE交易对添加流动性获得此代币):`0x32a829bbc5b3ced5cf76108ce537e4f9be3bbdb9` * PancakeSwap tBNB-SIE LP 质押合约:`0x4D53fba2Ee413283E902176316858AB1aB522563` * PancakeSwap tBNB-GAS LP(在BNB/GAS交易对添加流动性获得此代币):`0x1d9d1be6d1ec2319c8b90a5107d5421b557312cf` * PancakeSwap tBNB-GAS LP 质押合约:`0xA0c96CE5984D3949eAdD517C2E2cD852104941C0` PancakeSwap 测试网地址:[Home | PancakeSwap - $4.075](https://pancakeswap.finance/?chainId=97) ## 方法列表 ### 查询方法 查询方法不会修改合约状态,通常使用 [eth_call](https://www.quicknode.com/docs/ethereum/eth_call) RPC 接口进行调用,当前可用的查询方法列表如下: * `startBlock() uint256` 返回开始计算奖励的区块高度。值为 0 时合约未初始化,当前区块高度大于等于此值时开始计算奖励。 * `endBlock() uint256` 返回结束计算奖励的区块高度。值为 0 时合约未初始化,当前区块高度大于等于此值时结束计算奖励。 * `poolInfo(uint256 pid) PoolInfo` 返回指定池子信息(`accTokenPerShare uint128, lastRewardBlock uint64, allocPoint uint64, totalStaked uint256`)。`lastRewardBlock` 表示上次奖励的区块高度,`allocPoint` 表示池子的奖励点数。 * `totalAllocPoint() uint256` 返回所有池子的总计奖励点数,每个池子会根据奖励点数权重分配 **SIE** 代币奖励。 * `pendingReward(uint256 pid, address user) uint256` 返回用户在指定池子的未领取的 **SIE** 代币奖励数量。 * `userInfo(uint256 pid, address user) UserInfo` 返回用户在指定池子的质押信息(`amount uint256, rewardDebt int256`)。`amount` 表示质押代币数量。 * `tokenPerBlock() uint128` 返回每个区块奖励代币的总数量,根据每个池子的奖励点数分配给每个池子的质押用户。 在线合约工具:[StakingSharedPoolL2 | Address 0x4D53fba2Ee413283E902176316858AB1aB522563 | BscScan](https://testnet.bscscan.com/address/0x4D53fba2Ee413283E902176316858AB1aB522563#readContract) ### 写入方法 * `stake(uint256 pid, uint256 amount, address to)` 质押代币到指定池子。`pid` 表示池子的ID,`amount` 表示质押的数量,`to` 表示用户的地址。**注意**:调用此接口之前必须确保质押合约拥有用户足额的代币授权,参考 [ERC-20 Token Standard | ethereum.org](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) 中 `approve` 方法。 * `unstake(uint256 pid, uint256 amount, address to)` 解除代币质押。`pid` 表示池子的ID,`amount` 表示质押的数量,`to` 表示用户到账地址。 * `claim(uint256 pid, address to)` 领取质押奖励。`pid` 表示池子的ID,`to` 表示用户到账地址。 * `unstakeAndClaim(uint256 pid, uint256 amount, address to)` 解除代币质押并领取质押奖励。`pid` 表示池子的ID,`amount` 表示质押的数量,`to` 表示用户到账地址。 在线合约工具:[StakingSharedPoolL2 | Address 0x4D53fba2Ee413283E902176316858AB1aB522563 | BscScan](https://testnet.bscscan.com/address/0x4D53fba2Ee413283E902176316858AB1aB522563#writeContract) ## 合约ABI **ERC20**:https://gist.github.com/veox/8800debbf56e24718f9f483e1e40c35c **StakingSharedPoolL2**:[StakingSharedPoolL2 | Address 0x4D53fba2Ee413283E902176316858AB1aB522563 | BscScan](https://testnet.bscscan.com/address/0x4D53fba2Ee413283E902176316858AB1aB522563#code) ## 计算规则 **Annual Percentage Rate (APR)** 1. 查询Total Staked并将单位转换为美元 2. 查询Today’s Rewards并将单位转换为美元 3. 用第二步计算的值除以第一步计算的值然后乘以365 **Total Rewards** ```js let blocks = StakingSharedPoolL2.endBlock() - StakingSharedPoolL2.startBlock() let tokenPerBlock = StakingSharedPoolL2.tokenPerBlock() let allocPoint = StakingSharedPoolL2.pollInfo(pid).allocPoint; return tokenPerBlock * blocks * (allocPoint / StakingSharedPoolL2.totalAllocPoint()) ``` **Today's Rewards** 每个区块奖励数量乘以每天产生的区块数(币安链三秒产生一个区块) ```js let tokenPerBlock = StakingSharedPoolL2.tokenPerBlock() let allocPoint = StakingSharedPoolL2.pollInfo(pid).allocPoint; return tokenPerBlock * (allocPoint / StakingSharedPoolL2.totalAllocPoint()) * (60 * 60 * 24 / 3) ``` **Total Staked** 1. 调用质押ERC20代币合约查询StakingSharedPoolL2合约地址的余额,比如查询SIE LP质押数量: `let balance = ERC20(0x32a829bbc5b3ced5cf76108ce537e4f9be3bbdb9).balanceOf(0x90c8ed1d838253e24d41983d6bc55674a4a27370)` 2. 用质押合约的SIE LP余额除以SIE LP的总发行量,然后乘以SIE LP的SIE余额: ``` let totalSupply = ERC20(0x32a829bbc5b3ced5cf76108ce537e4f9be3bbdb9).totalSupply() return (balance / totalSupply) * ERC20(0xe29d4e3ca2dc5e91729c508fce5a3e20ed2c34ea).balanceOf(0x32a829bbc5b3ced5cf76108ce537e4f9be3bbdb9) ``` **Staking Period** `(StakingSharedPoolL2.endBlock - StakingSharedPoolL2.startBlock) * 3 / (60 * 60 * 24)` **Your stake percentage** `StakingSharedPoolL2.userInfo(pid, user).amount / StakingSharedPoolL2.poolInfo(pid).totalStaked` **Ends in** 使用 RPC 接口 `eth_blockNumber` 获取当前区块高度。 `(StakingSharedPoolL2.endBlock - currentBloack) * 3 / (60 * 60 * 24)` ## 参考资料 [blockchain - web3 - 使用metamask 调用某个contract 的方法 - 申思维的技术站点-ruby/rails/titanium/敏捷方法论/测试驱动/自动化/全栈攻城狮/jquery/极客/直男 (siwei.me)](http://siwei.me/blog/posts/blockchain-web3-metamask-contract)