[TWIL] Week of June 30, 2024

[TWIL] Week of June 30, 2024

·

3 min read

This week, the first after the OCS Buildathon, I dedicated my time to refactoring and researching upgradability access controls for our smart contracts. Here are the key insights and lessons I learned during this process.

Smart Contract Address Conflict

While refactoring code from the OCS Buildathon, I stumbled upon an unexpected issue: an onboarded artist reported seeing music he didn’t own on his profile page. Knowing the specific API route in question, I delved into the API route handler to identify the problem. Initially, my database query seemed straightforward—fetch all music data where the music NFT smart contract address matches the user's owned contracts. However, our platform supports both Polygon PoS and Base, which complicated matters.

Upon searching for the same smart contract address on both Polygonscan and Basescan, I discovered two distinct smart contracts, each deployed on a different chain. This revealed a critical oversight: smart contract addresses can be identical across different blockchains. For those familiar with how smart contract addresses are generated, this might seem obvious, but it caught me off guard while adding Base support.

Smart contract addresses are generated using the deployer’s address and a nonce, explaining why the two conflicting contracts shared the same address—they had the same deployer and nonce but were on different chains. The lesson here is clear: a smart contract address is unique within a single blockchain but not across different EVM-compatible blockchains.

To resolve the issue, I modified the query to include the blockchain type alongside the smart contract address, ensuring Prisma queries only the correct contract. With this newfound knowledge, we can avoid this pitfall in the future, or at least understand it better if it happens again.

OpenZeppelin Defender + Safe Wallet

Since we had some spare time for maintenance work, I decided to migrate from a company EOA to a multi-sig account. The rationale was simple: sharing our sole private key with an expanding team of developers would be highly imprudent. Our expectations for the new multi-sig account were clear:

  • Upgrading smart contracts requires multiple owners' approval

  • Certain smart contract methods can only be invoked if approved by multiple owners

  • Seamless support for upgrading smart contracts inheriting OpenZeppelin's upgradeable contracts

For the multi-sig component, Safe wallet came to mind. It's a well-known multi-sig wallet with a web app for easy interaction. However, Safe's app lacked UIs for smart contract upgrades. This led me to discover OpenZeppelin Defender, a SaaS product for smart contract development. It offers features like code inspection, auditing, deployment, and most importantly for us, UIs for deploying and upgrading smart contracts via Safe wallet. To evaluate its suitability, I experimented with deploying and upgrading smart contracts on multiple testnets.

During this testing phase, I encountered several issues:

  1. Safe wallet isn't yet supported on both Polygon Amoy and Base Sepolia, which are critical for us.

  2. Defender's app felt clunky, with long UI loading times and no error messages for failed processes, making debugging difficult.

  3. The Professional tier pricing is quite steep for an early startup. Although the free tier had no limitations on deploying and upgrading, the pricing page indicated a cap of 5 transactions, which is insufficient.

Despite these downsides, which are understandable given OpenZeppelin's fairly recent public launch of Defender V2, we also identified a few problems with Safe wallet for our purposes:

  • Safe doesn't have Polygon Amoy support on their roadmap yet. Although it's just a testnet, setting it up again with an EOA incurs significant testnet Matic costs for redeployment if the EOA is compromised.

  • Safe app lacks fine-grained access control. For instance, requiring a specific EOA for transaction approvals isn't possible since it only supports threshold-based approvals.

Given these challenges, I decided against using both Safe wallet and OpenZeppelin Defender. Instead, I opted to implement our own multi-sig smart contract for access controls. I'll discuss this in detail in the next TWIL article. For now, happy coding, everyone ☕️