How to Stress the IBC Security Model to Win Game of Zones

When we started thinking about Game of Zones in 2019, one of the most important goals we set was to use the challenge to prepare network operators for a whole new internet of blockchains. Once participants master liveness and throughput during Game of Zones, their final task will be to stress test the IBC Security Model. This exercise in adversarial thinking is designed to help teams identify and detect deception attacks in the wild, and to encourage the development of observability tooling to monitor for and alert on confusion attacks on the network.

The Double Spend Problem

Blockchains are notorious for attempting to implement solutions for the double spend problem. But the typical approach to solving this problem usually requires a world computer that runs about as fast as a calculator. Trying to scale solutions to the double spend problem has driven innovation and demand for zero knowledge proofs, random beacons, and complex sharding architectures. 

In designing IBC, we took a different approach that was inspired by the early works of the Agoric team and we focused on sovereignty. Core concept of sovereignty is that every user of a system needs to look at their own trust boundaries and preferences when choosing what chains, objects and tokens to interact with. With Game of Zones, we get to make that process of attack and defense real.

Token Distribution and ICS 20

At the launch of the GoZ Hub, we will be distributing tokens to each participating zone. Each of the zones will receive an equal number of tokens at the beginning of the competition, and those tokens will circulate in the IBC Network. While those tokens will not be a deciding factor in the first two phases of the competition, they are very important in assessing performance during the Phase 3. This is when we will look for confusion and deception attacks that trick users into accepting tokens that have been counterfeited and debased as if they were the real deal. The team with the most coins on the Hub may be the most likely to win. 

To compete in Game of Zones, your chain must support the ICS20 token transfer protocols during Phase 1 and Phase 2. If you want to bring a chain without ICS 20 support in the third phase, we suggest running a standard gaia in the first and second phases. We will be judging other application protocols during Phase 3, but they won’t be able to test the security model in the same way.

Confusion + Deception Attacks

One trend that we expect to emerge from participating teams during Phase 3 is fraudulent coin generation. An interesting implementation of this could be creating fractional exchange rates that enable zones to mint new coins out of nothing, and then send them on to other zones to convince other players to accept these coins. Though these tokens would never be redeemable, it would be difficult to judge whether they are valid coins or not.

Teams that are considering fraudulent coin strategies should pay special attention to the logic in the ics-20 implementation. Carefully manipulating the escrow and denom creation may also be a successful approach to trying to create underhanded state machines.

   if source {
       // clear the denomination from the prefix to send the coins to the escrow account
       coins := make(sdk.Coins, len(amount))
       for i, coin := range amount {
           if strings.HasPrefix(coin.Denom, prefix) {
               coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount)
           } else {
               coins[i] = coin
       // escrow tokens if the destination chain is the same as the sender's
       escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel)
       // escrow source tokens. It fails if balance insufficient.
       if err := k.bankKeeper.SendCoins(
           ctx, sender, escrowAddress, coins,
       ); err != nil {
           return err
   } else {
       // build the receiving denomination prefix if it's not present
       prefix = types.GetDenomPrefix(sourcePort, sourceChannel)
       for _, coin := range amount {
           if !strings.HasPrefix(coin.Denom, prefix) {
               return sdkerrors.Wrapf(types.ErrInvalidDenomForTransfer, "denom was: %s", coin.Denom)
       // transfer the coins to the module account and burn them
       if err := k.supplyKeeper.SendCoinsFromAccountToModule(
           ctx, sender, types.GetModuleAccountName(), amount,
       ); err != nil {
           return err
       // burn vouchers from the sender's balance if the source is from another chain
       if err := k.supplyKeeper.BurnCoins(
           ctx, types.GetModuleAccountName(), amount,
       ); err != nil {
           // NOTE: should not happen as the module account was
           // retrieved on the step above and it has enough balance
           // to burn.
           return err

Other attacks we expect to see during the competition include using a validator set to create difficult to detect light client forks and using state machines that conceal back doors and create tokens with arbitrary denominations to trick IBC users. Hopefully, we will see new ideas that we haven’t thought of before: to win this round of Game of Zones, teams will need to show their work by publishing technical details and write ups of their attacks once they’ve been carried out.

Has your team started working on your strategy for Phase 3? If not, take a closer look at ICS 20 and spend an afternoon with your team thinking about you would defend against deception attacks.