Turn your stories into NFTs

0 Following     0 Follower

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:

  1. go to SpookySwap to buy cherries (get CHRY token)
  2. allow the StoryPress smart contract to spend some of your cherries (using the Allowance link in the top right toolbar)
  3. 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:

  1. simply send some FTM to that contract
  2. 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:

// 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 {


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.

Reactions are currently disabled. They will return soon.

⏪ Previous Story

0xedB0...3484 avatar

v0.10.5 Better thumbnails on story cards

Small user interface update. Story card thumbnails are now nicely cropped so that they don't get squashed.
by 0xedB0...3484

⏩ Next Story

0xedB0...3484 avatar

v0.10.6: simpler onboarding UI

A few days after simpler onboarding, here is at last the small widget that allows you to easily get cherries ...
by 0xedB0...3484