Outlined below are the common operations associated with yield farming:
Deposit LP Tokens to a Farm
Deposit any amount of LP tokens to an existing farm to earn additional yield.
Function name: deposit
โฝ Recommended gas: 210,000 gwei (~ $0.018 USD)
Parameter Name | Description |
---|
uint256 _pid | Liquidity pool id |
uint256 _amount | LP token amount in its smallest unit |
function deposit(uint256 _pid, uint256 _amount) external payable nonReentrant {
require(msg.value >= tinycentsToTinybars(depositFee), 'msg.value < depositFee');
// send rent to rentPayer
(bool result, ) = rentPayer.call{value: msg.value}("");
if (!result) {
emit DidNotReceiveHbar(rentPayer, msg.value);
}
UserInfo storage user = userInfo[_pid][msg.sender];
PoolInfo storage pool = poolInfo[_pid];
updatePool(_pid);
uint256 pending = (user.amount * pool.accSaucePerShare / 1e12) - user.rewardDebt;
uint256 pendingHbar = (user.amount * pool.accHBARPerShare / 1e12) - user.rewardDebtHbar;
user.amount = user.amount + _amount;
user.rewardDebt = user.amount * pool.accSaucePerShare / 1e12;
user.rewardDebtHbar = user.amount * pool.accHBARPerShare / 1e12;
if(pending > 0) {
safeSauceTransfer(msg.sender, pending);
}
if (_amount > 0) {
safeTransferToken(pool.lpToken, msg.sender, address(this), _amount.toInt256().toInt64());
}
emit Deposit(msg.sender, _pid, _amount);
if (pendingHbar > 0) {
safeHBARTransfer(msg.sender, pendingHbar);
}
}
A spender allowance for the Farm contract is required for the LP token.
It costs $0.25 USD, payable in HBAR, to deposit the tokens into a farm. To get the current deposit creation fee, call the depositFee() method from the Farm contract. This will will return the current value expressed in Tinycent. To accurately convert this value to Tinybar, query the exchange rate from /api/v1/network/exchangerate
Code Overview
Resources:import {
ContractFunctionParameters,
ContractExecuteTransaction,
AccountAllowanceApproveTransaction,
..
} from '@hashgraph/sdk';
//Client pre-checks:
// - Farm contract has spender allowance for the LP token
const params = new ContractFunctionParameters();
params.addUint256(poolId); //uint _pid
params.addUint256(lpTokenAmount); //uint _amount
await new ContractExecuteTransaction()
.setPayableAmount(depositFeeInHbar)
.setContractId(farmContractId)
.setGas(gasLim)
.setFunction('deposit', params)
.execute(client);
Get Userโs Current Farm Reward
Get current HBAR and SAUCE yield reward values for a user
Function name: pendingSauce
โฝ No gas cost
Parameter Name | Description |
---|
uint256 _pid | Liquidity pool id |
address _user | Userโs solidity address |
function pendingSauce(uint256 _pid, address _user) external view returns (uint256, uint256) {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accSaucePerShare = pool.accSaucePerShare;
uint256 accHBARPerShare = pool.accHBARPerShare;
uint256 lpSupply = IERC20(pool.lpToken).balanceOf(address(this));
if (block.timestamp > pool.lastRewardTime && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp);
uint256 sauceReward = multiplier * (saucePerSecond) * (pool.allocPoint) / (totalAllocPoint);
uint256 hbarReward = multiplier * (hbarPerSecond) * (pool.allocPoint) / (totalAllocPoint);
accSaucePerShare = accSaucePerShare + (sauceReward * (1e12) / (lpSupply));
accHBARPerShare = accHBARPerShare + (hbarReward * (1e12) / (lpSupply));
}
return (user.amount * (accSaucePerShare) / (1e12) - (user.rewardDebt), user.amount * (accHBARPerShare) / (1e12) - (user.rewardDebtHbar));
}
Code Overview
Resources:import * as ethers from 'ethers'; //V6
//Set one of Hedera's JSON RPC Relay as the provider
const provider = new ethers.JsonRpcProvider(hederaJsonRelayUrl, '', {
batchMaxCount: 1, //workaround for V6
});
const interfaces = new ethers.Interface([
'function pendingSauce(uint256 _pid, address _user) external view returns (uint256, uint256)'
]);
const farmContract = new ethers.Contract(farmEvmAddress, interfaces.fragments, provider);
const result = await farmContract.pendingSauce(poolId, userEvmAddress);
const pendingSauceTiny = result[0]; //uint256
const pendingTinybar = result[1]; //uint256
Withdraw LP Tokens from a Farm
Withdraw any amount of LP tokens from an existing farm.
Function name: withdraw
โฝ Recommended gas: 190,000 gwei (~ $0.016 USD)
Parameter Name | Description |
---|
uint256 _pid | Liquidity pool id |
uint256 _amount | LP token amount in its smallest unit |
function withdraw(uint256 _pid, uint256 _amount) external nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount, "withdraw: not good");
updatePool(_pid);
uint256 pending = (user.amount * pool.accSaucePerShare / 1e12) - user.rewardDebt;
uint256 pendingHbar = (user.amount * pool.accHBARPerShare / 1e12) - user.rewardDebtHbar;
user.amount = user.amount - _amount;
user.rewardDebt = user.amount * pool.accSaucePerShare / 1e12;
user.rewardDebtHbar = user.amount * pool.accHBARPerShare / 1e12;
if(pending > 0) {
safeSauceTransfer(msg.sender, pending);
}
if(_amount > 0) {
safeTransferToken(address(pool.lpToken), address(this), msg.sender, _amount.toInt256().toInt64());
}
emit Withdraw(msg.sender, _pid, _amount);
if (pendingHbar > 0) {
safeHBARTransfer(msg.sender, pendingHbar);
}
}
Code Overview
Resources:import {
ContractFunctionParameters,
ContractExecuteTransaction,
..
} from '@hashgraph/sdk';
const params = new ContractFunctionParameters();
params.addUint256(poolId); //uint _pid
params.addUint256(lpTokenAmount); //uint _amount
await new ContractExecuteTransaction()
.setContractId(farmContractId)
.setGas(gasLim)
.setFunction('withdraw', params)
.execute(client);