Outlined below are the common operations associated with single-sided staking:
Get xSAUCE Amount from SAUCE
Get the calculated xSAUCE amount from a given SAUCE amount.
Function name: sauceForxSauce ⛽ No gas cost
Parameter Name | Description |
---|
uint256 _sauceAmount | SAUCE amount in its smallest unit |
function sauceForxSauce(uint256 _sauceAmount) external view returns (uint256 xSauceAmount_) {
uint256 totalSauce = IERC20(sauce).balanceOf(address(this));
uint256 totalxSauce = IERC20(xSauce).totalSupply();
if (totalxSauce == 0 || totalSauce == 0) {
xSauceAmount_ = _sauceAmount;
}
else {
xSauceAmount_ = _sauceAmount * (totalxSauce) / (totalSauce);
}
}
Code Overview
Resources:
//Typescript
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 sauceForxSauce(uint256 _sauceAmount) external view returns (uint256 xSauceAmount_)'
]);
const mothershipContract = new ethers.Contract(mothershipEvmAddress, interfaces.fragments, provider);
const result = await mothershipContract.sauceForxSauce(sauceAmountTiny);
const xSauceAmount = result[0]; //uint256 xSauceAmount_ - in token's smallest unit
Resources:
//Typescript
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 sauceForxSauce(uint256 _sauceAmount) external view returns (uint256 xSauceAmount_)'
]);
const mothershipContract = new ethers.Contract(mothershipEvmAddress, interfaces.fragments, provider);
const result = await mothershipContract.sauceForxSauce(sauceAmountTiny);
const xSauceAmount = result[0]; //uint256 xSauceAmount_ - in token's smallest unit
Stake SAUCE Tokens for xSAUCE
Stake any amount of SAUCE tokens in exchange for xSAUCE tokens.
Function name: enter ⛽ Recommended gas: 100,000 gwei (~ $0.009 USD)
Parameter Name | Description |
---|
uint256 _amount | The amount of SAUCE to stake in its smallest unit |
function enter(uint256 _amount) external {
uint256 totalSauce = IERC20(sauce).balanceOf(address(this));
uint256 totalShares = IERC20(xSauce).totalSupply();
safeTransferToken(sauce, msg.sender, address(this), _amount);
if (totalShares == 0 || totalSauce == 0) {
safeMintToken(xSauce, _amount, new bytes[](0));
safeTransferToken(xSauce, address(this), msg.sender, _amount);
}
// Calculate and mint the amount of xSAUCE the SAUCE is worth. The ratio will change overtime, as xSAUCE is burned/minted and SAUCE deposited + gained from fees / withdrawn.
else {
uint256 what = _amount * (totalShares) / (totalSauce);
safeMintToken(xSauce, what, new bytes[](0));
safeTransferToken(xSauce, address(this), msg.sender, what);
}
}
A spender allowance for the Mothership contract is required for the SAUCE token.
To calculate the amount of xSAUCE tokens a user will receive from a given SAUCE amount, use the sauceForXSauce() Solidity function in MotherShip.sol. Alternatively calculate the amount using the current SAUCE/xSAUCE ratio value.
Code Overview
Resources:
import {
ContractFunctionParameters,
ContractExecuteTransaction,
AccountAllowanceApproveTransaction,
TokenAssociateTransaction,
..
} from '@hashgraph/sdk';
//Client pre-checks:
// - XSAUCE token is associated
// - Mothership contract has spender allowance for the SAUCE token
const params = new ContractFunctionParameters();
params.addUint256(sauceAmountTiny); //uint _amount
await new ContractExecuteTransaction()
.setContractId(mothershipContractId)
.setGas(gasLim)
.setFunction('enter', params)
.execute(client);
Resources:
import {
ContractFunctionParameters,
ContractExecuteTransaction,
AccountAllowanceApproveTransaction,
TokenAssociateTransaction,
..
} from '@hashgraph/sdk';
//Client pre-checks:
// - XSAUCE token is associated
// - Mothership contract has spender allowance for the SAUCE token
const params = new ContractFunctionParameters();
params.addUint256(sauceAmountTiny); //uint _amount
await new ContractExecuteTransaction()
.setContractId(mothershipContractId)
.setGas(gasLim)
.setFunction('enter', params)
.execute(client);
Get SAUCE Amount from xSAUCE
Get the calculated SAUCE amount from a given xSAUCE amount
Function name: xSauceForSauce ⛽ No gas cost
Parameter Name | Description |
---|
uint256 _xSauceAmount | xSAUCE amount in its smallest unit |
function xSauceForSauce(uint256 _xSauceAmount) external view returns (uint256 sauceAmount_) {
uint256 totalxSauce = IERC20(xSauce).totalSupply();
sauceAmount_ = _xSauceAmount * (IERC20(sauce).balanceOf(address(this))) / (totalxSauce);
}
Code Overview
Resources:
//Typescript
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 xSauceForSauce(uint256 _xSauceAmount) external view returns (uint256 sauceAmount_)'
]);
const mothershipContract = new ethers.Contract(mothershipEvmAddress, interfaces.fragments, provider);
const result = await mothershipContract.xSauceForSauce(xSauceAmountTiny);
const sauceAmount = result[0]; //uint256 sauceAmount_ - in token's smallest unit
Resources:
//Typescript
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 xSauceForSauce(uint256 _xSauceAmount) external view returns (uint256 sauceAmount_)'
]);
const mothershipContract = new ethers.Contract(mothershipEvmAddress, interfaces.fragments, provider);
const result = await mothershipContract.xSauceForSauce(xSauceAmountTiny);
const sauceAmount = result[0]; //uint256 sauceAmount_ - in token's smallest unit
Unstake xSAUCE Tokens for SAUCE
Unstake any amount of xSAUCE tokens in exchange for SAUCE tokens.
Function name: leave ⛽ Recommended gas: 100,000 gwei (~ $0.009 USD)
Parameter Name | Description |
---|
uint256 _share | The amount of xSAUCE to unstake in its smallest unit |
function leave(uint256 _share) external {
uint256 totalShares = IERC20(xSauce).totalSupply();
uint256 what = _share * (IERC20(sauce).balanceOf(address(this))) / (totalShares);
safeTransferToken(xSauce, msg.sender, address(this), _share);
safeBurnToken(xSauce, address(this), _share, new int64[](0));
safeTransferToken(sauce, address(this), msg.sender, what);
}
To calculate the amount of SAUCE tokens a user will receive from a given xSAUCE amount, use the xSauceForSauce() Solidity function in MotherShip.sol. Alternatively calculate the output amount using the current SAUCE/xSAUCE ratio value.
Code Overview
Resources:
import {
ContractFunctionParameters,
ContractExecuteTransaction,
AccountAllowanceApproveTransaction,
..
} from '@hashgraph/sdk';
//Client pre-checks:
// - SAUCE token is associated
// - Mothership contract has spender allowance for the XSAUCE token
const params = new ContractFunctionParameters();
params.addUint256(sauceAmountTiny); //uint _share
await new ContractExecuteTransaction()
.setContractId(mothershipContractId)
.setGas(gasLim)
.setFunction('leave', params)
.execute(client);
Resources:
import {
ContractFunctionParameters,
ContractExecuteTransaction,
AccountAllowanceApproveTransaction,
..
} from '@hashgraph/sdk';
//Client pre-checks:
// - SAUCE token is associated
// - Mothership contract has spender allowance for the XSAUCE token
const params = new ContractFunctionParameters();
params.addUint256(sauceAmountTiny); //uint _share
await new ContractExecuteTransaction()
.setContractId(mothershipContractId)
.setGas(gasLim)
.setFunction('leave', params)
.execute(client);