Simpler onboarding
To participate in StoryPress (publish stories, write comments, make reactions ...) you need to spend cherries (mainly to prevent spam, bots, hate, ...).
For this, you have to:
- go to SpookySwap to buy cherries (get CHRY token)
- allow the StoryPress smart contract to spend some of your cherries (using the Allowance link in the top right toolbar)
- and eventually fill your internal StoryPress balance in case you want spend less gas in fees
This is kind of dull, especially if you are not familiar with Decentralised Exchanges (DEX) like SpookySwap.
So here is a smart contract that makes it simpler for you:
- simply send some FTM to that contract
- your StoryPress internal balance is credited in cherries and you can have fun right away
Onboarding smart contract: the code
In case you are curious, or suspicious, or you also would like to write this kind of smart contract, here is the code, under MIT licence, so use it as you wish.
Keep in mind:
- CHRY = Cherry token in the original Cherry ERC-20 smart contract
- CHRF = Cherry tokens that are kept on your behalf inside the Cherrific smart contract. If you want more details about CHRF, please read CHRF, using your StoryPress internal balance
// Onboard.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* This contract is used to onboard new users to Cherrific.io.
*
* Instead of:
* - buy CHRY tokens on SpookySwap
* - allow Cherrific smart contract to spend your CHRY tokens
* - fill your internal CHRY balance (=CHRF) to use Cherrific
*
* You can simply:
* - send FTM to this contract
* - it will fill your internal CHRY balance for you (= CHRF)
*
* This saves you from having to buy CHRY tokens on SpookySwap
* and the allow step.
*
* The contract checks it has enough CHRF tokens to fill your balance.
* If not, transaction will revert.
*
* Anyone can fill the CHRF balance of that contract. (that is, the CHRY
* balance of this contract inside Cherrific smart contract)
*
* Owner powers:
* - change ownership of contract
* - withdraw FTM from contract
*/
import "./abstractOwnable.sol";
import "./IERC20.sol";
import "./IOracle.sol";
import "./ICherrificUser.sol";
contract Onboard is Ownable {
// ==== Events ====
event Swaped(address indexed user, uint CHRFamount, uint FTMamount);
// ==== Constants ====
address constant cherrific = 0xD022D9AC8bdE380B028682664b5F58d034254BEf;
address constant oracle = 0x2bcC8dA3fE1BF5637262c9c05663490f14C981d6;
// ==== Storage ====
// None.
// The only state is the CHRF balance of this contract in the Cherrific smart contract.
// ==== Views ====
// return the CHRF balance of this contract
function balance() public view returns (uint) {
return IERC20(cherrific).balanceOf(address(this));
}
// estimage how much CHRF will be bought with the FTM sent
function estimate(uint value) public view returns (uint) {
// get the latest CHRY TWAP from oracle
uint twap = IOracle(oracle).twap();
// compute how much CHRF will be bought with the FTM sent
// 15% premium on price
// this amount is rounded to integer with 18 0 decimals
uint amount = value / twap * 85 / 100 * 1e18;
// check if contract has enough CHRF
require(balance() >= amount, "This contract does not have enough CHRF");
// check if user already has an accound on Cherrific
// if not, remove one CHRF from tranfer amount
// because one CHRF will be taken from this contract balance to create the account
try ICherrificUser(cherrific).getUser(msg.sender) {
return amount;
} catch Error(string memory) {
// if not, remove one CHRF from tranfer amount
// because one CHRF will be taken from this contract balance to create the account
amount -= 1e18;
return amount;
}
}
// ==== Modifiers ====
// default receive function
// will be called when user sends FTM to this contract
// it cannot return anything
receive() external payable {
// transfer CHRF to user on Cherrific smart contract
uint amount = estimate(msg.value);
IERC20(cherrific).transfer(msg.sender, amount);
emit Swaped(msg.sender, amount, msg.value);
}
// ==== Governance ====
// withdran all FTM from contract
function withdraw() public onlyOwner {
payable(owner()).transfer(address(this).balance);
}
}
It is deployed at address 0xE1569D71FD42a01c8e14F081C567BF791FBD54B4 and verified.
The oracle is used to compute the Time Weighted Avera Price (TWAP) of Cherries over 6 hour long epochs, so that people won't be able to manipulate the liquidity pool in order to get cherries under their market price.
A 15% price premium is applied to the TWAP price. If you find it too high, please go to SpookySwap. This contract is not the recommended to get Cherries at their best price, it's just here so that you can easily grab a few cherries without the fuss of going to SpookySwap.
Now that the contract is written and deployed, I need to add some UI to make it easy for you to use from StoryPress.info.
Edit: a small widget has finally been added so you can easily grab some cherries.