Claiming Incident Post-Mortem: Reflection & Measures Taken (6 Apr, 2023)
6 April 2023, it’s TGE and our first $ARKEN claim day. But no one can claim them. Here’s what happened from the technical side of things.
We will talk about this in two parts of the system: Smart Contract and Front-end.
The Smart Contract Issues
Before delving into the incident and explanation of what occurred, it’s important to note that there are 3 contracts deployed for claiming Arken token:
1. The contract for claiming our Airdrop 1st Round, total $10M.
ArkenTokenClaim: https://arbiscan.io/address/0xF02F04335F1996830240994444Cb173FE6Ab2c63
2. The contract for claiming token from Public Sale on Impossible Finance, total $325M.
ArkenTokenClaimIF: https://arbiscan.io/address/0xa4f9bdcd96c48a276cc686870a3e0d2de534ba57
3. The contract for claiming token from Public Sale on our Arken Finance website, total $250M.
ArkenTokenPublicSale: https://arbiscan.io/address/0x0aeb4700Ae0985E860aF6Eb25810050f4254880b
What Happened During the Claiming Period
On 6 April 2023 at 2pm UTC, during the claiming period of Arken tokens, it turned out that some wallets were able to claim $ARKEN from ArkenTokenClaimIF contract and ArkenTokenPublicSale contract, but no one was able to claim on ArkenTokenClaim contract.
Arken made a careful investigation on ArkenTokenClaim contract immediately.
Detailed Explanation on the Issues
The error we got when we attempted to claim was ArkenTokenClaim: invalid signature which signified that there was something wrong with our signature. (To know more why we use signature for this contract, please read here: Lazy Minting)
Wallets from 3 types of campaign can claim the tokens from this contract.
enum Kind {
THANKYOU,
FOLLOW_AND_SHARE,
ARKEN_AIRDROP_1
}
Upon testing and making initial investigation, we discovered that we were able to claim the THANKYOU campaign, which led us to believe that there was an issue with our code in signing the claiming signatures for the other two campaigns.
After further inspection, we discovered a bug in the part of the code. As shown in the image below, instead of using 1 and 2 when generating signatures for FOLLOW_AND_SHARE and ARKEN_AIRDROP_1 respectively, we mistakenly use 0 which corresponds with THANKYOU campaign on both.
As a result, the signatures intended for FOLLOW_AND_SHARE and ARKEN_AIRDROP_1 were unusable.
What Did Arken Do to Address the Issue
Here was how we fixed this issue:
After re-signing all the signatures with a new wallet, the valid signers on the contract were updated and functioned properly.
Here’s the transaction for the updated signers: https://arbiscan.io/tx/0xdaa26412c205c26492e9c0a200b191f49fd8d979fb80bc9f76c1cd047aa53daa
However, even after resolving the issue on ArkenTokenClaimIF and ArkenTokenPublicSale contracts, some users still couldn’t claim the token through our site. The team is currently investigating the issue on the front-end.
The front-end Issues
As users were unable to claim $ARKEN tokens through our site, but some wallets were able to successfully claim tokens through certain contracts that we observed on arbiscan.io. We suspected that there may be other factors at play beyond just an issue with the ArkenTokenClaim contract. So, we dug into the front-end codes.
Detailed Explanation on the Issues
At first, the interface and information available between our back-end and front-end team is not enough for creating a great UX which we strives for.
Namely, the first version of the contract doesn’t have a function that returns whether or not a wallet has already claimed $ARKEN from a campaign. Following this, we chose to use gas estimation to determine if a wallet can or can not claim a specific campaign by trying — estimating the gas — to call claim on the contract. If it fails with a message of already claimed or something else that would determine that the wallet can not claim from that campaign, then we display the information accordingly.
This means that for this to works, the user has to connect the wallet then change the chain to Arbitrum just to see if their wallet can claim or not.
What Did Arken Do to Address the Issue
In effort to improve our UX, we determine this to be too much of a pain for our users. We want our user to see whether they have any claimable $ARKEN or not without having to worry about switching the chain on their wallet. So we updated the contract to include the claimed and other functions for the front-end to get data from.
This eliminates the need for user to switch the chain to Arbitrum before seeing any information, thus abstracting chain switching complexity.
This feature would also goes along with our goal of providing our user the best UX on the DeFi space, so we as a team decided to change our code and implemented it.
But along the way through our development, we made a mistake and changed the code responsible for interacting with our smart contract. The wallet signer that should have been connected with the contract was removed in the process.
This introduced a bug at the very last step when we actually interact with the contract. Although we could still estimating the gas in our functions, when it comes to executing the transaction, it failed. This bugged last step behavior slipped through our testing, and when we caught it, it was too late.
Let this be a lesson for us. While we believe improving our users’ experience is a good thing, we need to do better.
For reference, this was before:
And this was after:
Codes affected after:
The function that cause an error:
After all measures were taken to fix these issues, we were able to resume the claiming process again.
Epilogue
We would like to apologize that we failed to deliver the best token claim experience as we hope it to be. As we committed to keep being better at building product, we will learn from this mistake. We will try our best to deliver better products to our community.