How all funds can be stolen by the developers from ShibaSwap staking contracts — Please do not use it.

Rugs — Eric Prouzet

The recently launched dapp on the Ethereum blockchain, Shibaswap, has a high APR for staking Liquidity Provider tokens, however, the developer can easy remove all liquidity staked in the smart contract and steal funds. Let’s walk through the code and show how it is unsafe, then show how the dev can fix this particular issue.

First a quick primer on Liquidity Pools, AMMs like Uniswap that allow you to swap between different tokens safely and efficiently, and LP staking programs:

Liquidity Pools:

Liquidity is typically represented by discrete orders placed by individuals onto a centrally operated order book. A participant looking to provide liquidity or make markets must actively manage their orders, continuously updating them in response to the activity of others in the marketplace.

While order books are foundational to finance and work great for certain usecases, they suffer from a few important limitations that are especially magnified when applied to a decentralized or blockchain-native setting. Order books require intermediary infrastructure to host the orderbook and match orders. This creates points of control and adds additional layers of complexity. They also require active participation and management from market makers who usually use sophsticated infrastructure and algorithms, limiting participation to advanced traders. Order books were invented in a world with relatively few assets being traded, so it is not surprising they aren’t ideal for an ecosystem where anyone can create their own token and those tokens usually have low liquidity. In sum, with the infrastrucural trade-offs presented by a platform like Ethereum, order books are not the native architecture for implementing a liquidity protocol on a blockchain.

Learn more about liquidity pools in the Uniswap docs here.

To reward users for providing the service of liquidity to the pools, some protocols reward users in additional tokens, increasing the APR of Liquidity Providers (LPs).

LPs promise to not remove their liquidity from the market, by staking their LP tokens. Shibaswap has staking like this, with very high rewards. However, you should not use it, because the LP tokens are not safe in the their staking contract.

Why ShibaSwap staking is unsafe

Users can lock pairs of assets like $GRT + $ETH into the AMM pool, and receive an LP token representing their share of the pool in exchange. The LP tokens are locked into the smart contract published at 0x94235659cf8b805b2c658f9ea2d6d6ddbb17c8d7. The developer helpfully verified the smart contract code using the hash of the code on Etherscan 👍.

This staking contract is owned by the address 0x4267a3ad7d20c2396ebb0fe72119984f7073761c. For most of today the contract was owned by a single person, but this was been updated to this new 0x4267 address. This owner address is actually another very recognizable smart contract, a Gnosis Safe. The safe has 9 members, and requires at least 6 of them to agree to a transaction before it can call any arbitrary code.

You can verify the owners yourself on the Gnosis safe site by importing the address above. Multiple of these Safe Owners are new accounts with 0 transactions and no ETH, so they are most likely just place holders for the ShibaSwap devs who can agree easily to call any owner only function on the staking contract.

One of the functions in the contract is called Migrate, which moves all LP tokens to any contract the dev wants. Despite moving the owner powers into a small group, this group still has the ability to steal all funds.

How funds can still be stolen

The migrate function is the main issue here. Here’s some code from their verified staking contract. I encourage you to double check this code I am showing is exactly what is deployed :)

// Set the migrator contract. Can only be called by the owner.
function setMigrator(IMigratorShib _migrator) public onlyOwner {
migrator = _migrator;
emit SetAddress("Migrator", msg.sender, address(_migrator));
// Migrate lp token to another lp contract. Can be called by anyone. We trust that migrator contract is good.
function migrate(uint256 _pid) public {
require(address(migrator) != address(0), "migrate: no migrator");
PoolInfo storage pool = poolInfo[_pid];
IERC20 lpToken = pool.lpToken;
uint256 bal = lpToken.balanceOf(address(this));
lpToken.safeApprove(address(migrator), bal);
IERC20 newLpToken = migrator.migrate(lpToken);
require(bal == newLpToken.balanceOf(address(this)), "migrate: bad");
pool.lpToken = newLpToken;

The setMigrator function allows the contract owner, which is the gnosis safe group, to set any arbitrary newly deployed smart contract as the “migrator”.

Next, the migrate function can be called by anyone at any time. But it requires a valid “migrator” to be set. If that arbitrary migrator contract is set, then a new LP token object is instantiated, and the variable bal is set to the smart contracts current holding of any LP token staked in this contract.

Next all the LP tokens (over $500M of various token types and ETH at the time of writing this) are moved to the new arbitrary migrator contract, and potentially useless “new Lp token”s are replaced. We have no way to know that the new migrator contract would actually allow staking users to unstake their tokens safely. Rather, the devs can simply deploy a new migrator contract which sends themselves all the LP tokens, set the “migrator” in the staking contract to this new one using the Gnosis Safe, and call the “migration” function to move everything over.

Hundreds of million of dollars in tokens could disappear at any moment in the current state should the developer choose.

How to fix

If the developer takes all of these steps this situation can be fixed, and funds could be safer.

1. Add a timelock contract so there is a long, 1 week+, delay between safe owners agreeing on some smart contract function call & that call being made. So if the safe owners agree to pull all the liquidity, it gives everyone time to pull out of the staking contract first. This should happen immediately and is really the bare minimum I would hope for.

2. Turn ownership over to a DAO made up of all the LP providers instead of 9 addresses controlled by the developer. This could be a longer term security sustainability measure

3. Redeploy their staking contracts to not even include an admin only “migration” function which allows moving all the funds anywhere, and start over. This should happen as soon as possible.

If the devs do all of these things immediately, I will take back my criticism and say this isn't a scam. Until then, this staking contract is a scam, despite hundreds of millions being locked into it.

Have questions? Upset that I would tarnish the good name of useless dogtokens that are clearly scams which have gone on far too long? Let me know.

Developer, kombucha brewer, eth punk, chess player, friend.