STAIK is a rewards-based token project, so it probably sounds strange to start off a Medium posting with the title we’ve chosen. Allow us to provide some context.
If you’re already familiar with rewards tokens, often referred to as “reflection” tokens, then you may already be familiar with Reflect Finance and Safemoon.
Essentially these projects incorporate some form of “tax” when their token is traded. Sometimes there is a “buy” tax for when you first acquire the token, and sometimes there is a “sell” tax for when you sell that token on for something else. In the case of some projects, there will be both a buy and a sell tax.
Usually this “tax” heads off to one of four places:
- The project developers wallets. The developers behind these projects often make unsubstantiated claims that the “tax” they are claiming will go towards development costs, or marketing fees, or exchange launches, etc.
- A liquidity pool on a DEX that the token first launched on (e.g. Uniswap, Sushiswap, etc.)
- A “burner” wallet. This is essentially a wallet address of 0x0000000000000000000000000000000000000000 or 0x000000000000000000000000000000000000dEaD — They are called “burner” wallets because nobody knows the private key for these wallets (and nobody ever will…. unless quantum computers eventually manage to crack them!) so tokens sent to these addresses are essentially out of circulation, and can never be used.
- Re-distributed to other remaining token holders
We’ll cover our own STAIK token distribution model in far greater detail on the four points above in another post.
In terms of rewards/reflection tokens in general, the key advantage over traditional DeFi “farming”, (which is when you add liquidity to a DEX liquidity pool, receiving the LP tokens representing that liquidity pool, and then deposit your LP tokens into a farming contract to earn rewards) is that you can keep your LP tokens safely in your wallet whilst still earning rewards. After all, if you lose your LP tokens, then you’ve effectively lost your liquidity for the pool on which you deposited in the first place.
Rewards/reflection tokens can be very powerful. These types of tokens usually incorporate some clever functionality inside the smart contract of the token itself, in order for the rewards or reflections to be distributed automatically, and because of this, the “template” of the smart contract token itself, which normally starts off as a standard ERC20 token, has various functional “features” added to it.
For example, if we look closer at the Reflect Finance (RFI) smart contract, we can see that the code begins by interfacing the standard ERC20 functions, as outlined in the Open Zeppelin standards:
https://etherscan.io/token/0xa1afffe3f4d611d252010e3eaf6f4d77088b0cd7#code
interface IERC20 {
// @dev Returns the amount of tokens in existence.
function totalSupply() external view returns (uint256);
// @dev Returns the amount of tokens owned by `account`.
function balanceOf(address account) external view returns (uint256);
// @dev Moves `amount` tokens from the caller's account to `recipient`.
// Returns a boolean value indicating whether the operation succeeded.
// Emits a {Transfer} event.
function transfer(address recipient, uint256 amount) external returns (bool);
// @dev Returns the remaining number of tokens that `spender` will be
// allowed to spend on behalf of `owner` through {transferFrom}. This is
// zero by default.
// This value changes when {approve} or {transferFrom} are called.
function allowance(address owner, address spender) external view returns (uint256);
// @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
// Returns a boolean value indicating whether the operation succeeded.
// Emits an {Approval} event.
function approve(address spender, uint256 amount) external returns (bool);
// @dev Moves `amount` tokens from `sender` to `recipient` using the
// allowance mechanism. `amount` is then deducted from the caller's
// allowance.
// Returns a boolean value indicating whether the operation succeeded.
// Emits a {Transfer} event.
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
// @dev Emitted when `value` tokens are moved from one account (`from`) to
// another (`to`).
// Note that `value` may be zero.
event Transfer(address indexed from, address indexed to, uint256 value);
// @dev Emitted when the allowance of a `spender` for an `owner` is set by
// a call to {approve}. `value` is the new allowance.
event Approval(address indexed owner, address indexed spender, uint256 value);
}
These core functions of an ERC20 token are added via the “interface IERC20” into a new Token project, so that they meet globally agreed-upon standards, and allow things like decentralized exchanges (DEX) to list them, offer liquidity pools for them, and ultimately allow people to trade them.
The Reflect token also inherits other libraries and utilities as per the Open Zeppelin standards.
Up to this point, the smart contract is relatively standard….it’s only once to get to the “meat” of the smart contract (starting on line 501 of the Smart Contract code) that the fundamentals of how reflections are handled is coded.
The point is that there is additional logic in the smart contract that extends the base functionality of ERC20.
At a high level, this can be seen as a good thing, because the additional smart contract functions allow holders of the Reflect Finance RFI token to earn reflection rewards. In the case of the RFI token, holders earn reflections whenever FRI tokens are bought OR sold. A 1% buy tax and a 1% sell tax is paid whenever you trade RFI, and it gets passed to other RFI holders. Conceptually, it’s a nice idea.
However in this instance, and in the case of every other rewards/reflections token we’ve come across, it has a couple of flaws.
(If you’d like through an incredibly in-depth breakdown of the contract, please check out this excellent document: https://reflect-contract-doc.netlify.app/)
Firstly, the RFI buy and sell tax % amount….
function _reflectFee(uint256 rFee, uint256 tFee) private {
_rTotal = _rTotal.sub(rFee);
_tFeeTotal = _tFeeTotal.add(tFee);
}
This is set to 1%, and regardless of any market conditions (bull market, bear market) the fee paid out will still be 1%
Imagine for a moment that you were a large holder of RFI tokens, and you decided that the crypto markets were not going well, so you wanted to sell your entire holding of RFI. Paying a 1% probably wouldn’t be that bad. You exit from the project, lose 1% and move on.
Now as an existing holder, the last thing you’d want during a bear market or during turbulent market conditions, is for large holders to sell their RFI tokens, as of course selling a token on a DEX will drive the price down:
( x * y = k … We’ll cover this in another Medium posting!)
So having a 1% sell fee isn’t exactly a big disincentive, and won’t put many people off wanting to sell. Not great if you’re an RFI holder.
A better approach
Wouldn’t it be nice if that sell % self-adjusted dynamically, based on real-time market conditions, and did so in such a way as to at least make the seller think very carefully about selling their token and lowering the overall price. For example, a 1% sell tax probably wouldn’t put off a seller in a turbulent market when the token holder wants to offload….. but a 20% sell tax for example, might be enough to make the person think again.
At the same time, if you had a “fixed” sell tax of a large amount, then sure it might dissuade holders from selling….. but at the same time it would massively discourage new investors from investing in the first place. After all, if you know that you’d take a 20% when you eventually want to sell your tokens (and let’s be honest about it, almost every single person looking to buy into a token project, will want to sell that token at some point later on at a profit!) then you might carefully re-consider.
For example, if you purchased 10,000 token “X” at $1 per token, costing you $10,000 and then you wanted to immediately sell your tokens, you’d only get back $8,000! That means you’d have to wait for the price of token “X” to reach $1.25 per token (25% increase!) before you could sell to break even, and that doesn’t even account for DEX fees, slippage, and gas fees.
So the ultimate goal here is that when markets are stable, you’d want the sell tax to be as little as possible, to encourage new investors….. but when markets are bad, and nobody is buying, you want the sell tax to be higher to discourage sell-offs. This is why we have a very clever function of our own, the Sell Pressure Reducer (SPF) — Again, we’ll cover this in far more detail in another posting.
The point of explaining this, is that additional “smart” features of a token contract, when bolted onto the core ERC20 token standards, often don’t play well with some DEX exchanges.
DEX’s charge a fee of their own when investors trade tokens. That’s how they make a living, and is the reason they exist in the first place. For example, Uniswap charge a fixed fee of 0.3% on all trades on version 2 of their DEX, and a selection of three fees (0.05%, 0.30%, and 1%) on version 3 of their DEX.
Up until now, Uniswap have clearly stated that they don’t support reflection tokens on their V3 DEX. This is because they use a “concentrated liquidity” model — https://docs.uniswap.org/concepts/protocol/concentrated-liquidity
Our approach to the code to ensure that STAIK token investors will not experience issues with trading via Uniswap v3 is what we have called UPNP or “Uniswap v3 Position NFT Pooling”
It’s worth highlighting one of the key differences for Liquidity providers on Uniswap V3, vs Uniswap V2. For Uniswap V2 (and the vast majority of Uniswap forks and clones) liquidity providers received fungible LP tokens when they added liquidity to a pool.
For V3, they instead receive an NFT token representing their fees. all fees generated held directly within the NFT itself.
What’s really interesting about this approach, is that these NFTs can be traded between wallets, and fees accrued by the position can be collected by the holder at any time.
Here are Uniswap v3 positions on OpenSea
The NFT tells you what Liquidity pair it represents, the fee percentage earned (in the image above, this is 0.05%) the NFT token ID, and the “concentrated liquidity” range inside which the NFT owner will earn fees. So in the image example above, the owner will earn fees whilst the USDT/DAI pair trades within the “tick” ranges of 276380 and 276270. If the pair trades outside these ranges, then the NFT owner will not earn fees.
This unique feature of Uniswap V3 is what complicates the liquidity provisioning for all other rewards-based tokens, but our approach in introducing “UPNP” into our smart contract logic, ensures that trading STAIK within the Uniswap v3 environment continues to work in the same way as it does for more traditional AMM DEX exchanges such as Sushiswap and Trader Joe.
Because our STAIK token accommodates BOTH V3 and legacy V2 DEX exchanges, we have identified our project as being a “Multi-DEX” solution.
(UPNP architecture details released after token audit)