Updating a Smart Pool Implementation

All Pie DAO smart pools are upgradeable because they use a proxy contract. At PieDAO we use our implementation of a simple proxy contract called pie-proxy.

Upgrading a contract is done by setting the implementation address on the proxy contract to the address of the new logic contract. Using this pattern allows smart pools to be upgraded while keeping the old storage.

Deploying a new implementation

Clone the pie-smart-pools repository and checkout master. Master contains the latest release which is considered stable and audited for mainnet use.

copy the contents of env.example to a new file called .env and edit the relevant values inside. DO NOT share this file with anyone as it will contain sensitive data.

Install all dependencies:


Build the project

yarn build

To deploy the implementation contract run the following command replacing the impl-name value with the name you would like to give to the implementation contract and the --network value with whichever network you want to deploy the contract to.

npx buidler deploy-smart-pool-implementation-complete --impl-name [IMPL-NAME] --network kovan

In your terminal you will see the address of the implementation, copy this for the next step.

Setting the new implementation

The pie-proxy instance has a proxyOwner address, only this address is capable of changing the implementation contract by calling setImplementation(address _newImplementation).

The smart pools are currently controlled by a multisig wallet. To change the implementation you should do the following steps.

  1. Connect your wallet.

  2. Add a transaction.

  3. Set destination to pool address.

  4. Set contract name.

  5. Set ABI (can be found on Etherscan).

  6. Select setImplementation method.

  7. Fill in the implementation address in the input.

  8. Send multi sig tx.

  9. Get enough confirmations by other multi sig owners.

  10. Enjoy your upgraded contract.

Testing procedure

Because Pie smart pools deal with real value it is important to take extra precaution when upgrading them to minimize the risk to users funds.

For BTC++ there is a private testing pool on mainnet at: 0x21909429c586fb739653e8e0b913b23fe30bacfa.

Before upgrading any pool we do a test run using this pool first. To do this we take the following steps:

  1. Deploy implementation (described above).

  2. Set cap to zero.

  3. Set implementation (described above).

  4. Set Controller to testing address.

Automated testing

The automated test tests this functionality on mainnet:

  1. Check the controller.

  2. Check if the cap is zero.

  3. Exiting the pool.

  4. Check if cap is enforced.

  5. Setting the cap.

  6. Joining the pool.

  7. Setting cap to zero

  8. Setting public swap from non public swap setter (should fail).

  9. Setting public swap setter from controller.

  10. Setting public swap to true.

  11. Setting public swap to false.

  12. Setting the tokenBinder

  13. Unbinding token from non tokenBinder address (should fail).

  14. Binding token from non tokenBinder address (should fail)

  15. Rebinding token from non tokenBinderAddress (should fail).

  16. Rebinding token from tokenBinderAddress.

  17. Binding token from tokenBinder address.

  18. Unbinding token from tokenBinder address.

  19. Setting token binder to 0x000...0000.

  20. Binding a token (should fail).

To run this test execute the following command:

POOL=[POOL_ADDRESS] npx buidler test ./mainnet-test/test.ts --network [rinkeby|mainnet]

This command will throw an error if something is not as expected.

Only AFTER these tests should the implementation be set on the actual smart pool contract. See above on how to do this.

Last updated