Rust smart contract development diary (10-2)
BlockSec
2022-04-03 04:13
本文约4501字,阅读全文需要约18分钟
This article brings you the contract interpretation of Sputnik_DAOv2::Factory Contract.

Preamble1. Sputnik-DAO Factory Contract

Sputnik-DAO adopts the creational factory design pattern (Factory Pattern) to realize the unified creation and management of the decentralized autonomous organization (DAO) of the platform.

This article will introduce the design and implementation of the Sputnik-DAO platform factory pattern (sputnikdao-factory) in detail.

The source code warehouse of the corresponding contract is located at: https://github.com/near-daos/sputnik-dao-contract/tree/518ad1d97614fff4b945aba75b6c8bd2483187a2

first level title

2. DAPP module function introduction

Open the DAPP page of the Sputnik DAO platform, it can be seen that many decentralized autonomous organizations have created and customized their own DAO instance objects (Sputnikdaov2 contract) on the platform.

As of March 2022, the most active DAO created under this platform is news.sputnik-dao.near, in which 3051 proposals (proposals) are in public voting or the status has been closed.

📄For the convenience of readers, the structure diagram of the contract is provided above for reference.

That is, all DAO instance contracts created based on the Sputnik DAO platform are deployed under the sub-accounts of the NEAR account, for example:

For the definition of subaccounts in NEAR Protocol, you can get a reference at https://docs.near.org/docs/concepts/account#subaccounts 🔗.

As shown in the figure below, decentralized organizations can openly initiate transactions on the NEAR main network, and create new DAO instances by calling the create() method provided by the sputnikdao-factory contract.

3. Interpretation of sputnikdao-factory contract code

In order to help you better understand the writing method of Rust factory mode contract, this article will deeply interpret the contract code of sputnikdao-factory.

3.1 Creating DAOs

The sputnikdao-factory contract status mainly consists of the following two parts:

The specific content of the args parameter after Base64 decoding is:

This content is exactly the contract configuration information required when executing the contract initialization method new() when deploying the multicall.sputnik-dao.near contract.

The following article will analyze the specific implementation of factory_manager.create_contract in detail:

The parameters of this function are specified as follows:

DAO basic information provided by the decentralized autonomous organization: Config

5. callback_method: Specifies the callback function after the create_contract() method is executed, which is used to maintain and process the information of the new DAO instance contract in this factory contract.

6. callback_args: Function parameters of the callback function.

The execution of this function is mainly divided into the following steps:

After the final DAO instance contract is deployed, the on_create() function will be called back at the end of the factory_manager.create_contract() execution code 32-53 lines.

The following is the internal code implementation of the callback function on_create:

The specific processing logic of this function is:

text

text

text

The code is located at: sputnikdao-factory2/src/lib.rs # Line136-149

The processing details of factory_manager.update_contract() are as follows: This interface can realize the call of the update() function in the corresponding DAO instance contract.

It is worth mentioning that:

During the analysis of Sputnik-DAO code, BlockSec found a serious security problem in its Factory contract, which will affect all contracts using Sputnik-DAO. After contacting the project party, the Issue was finally confirmed and fixed in time.

💡The security vulnerability is specifically described as:

In the previous version of the code, the public update() method provided by the sputinikdao factory contract lacked the following key assertion check. This results in the method being callable by anyone.

Coincidentally, the DAO instance contract (Sputnikdaov2 contract) allows the upgrade of this contract by Sputnik-DAO Factory through cross-contract calls by default.

The update() method implemented in the DAO instance contract is as follows, the code is located in sputnikdao2/src/upgrade.rs # Line 62

In line 9 of the above code, the value of factory_info.auto_update is set to True by default when the DAO instance contract deploys and calls the new() method for initialization.

The new() method of the DAO instance contract is implemented as follows: the code is located in sputnikdao2/src/lib.rs # Line 83-104

In summary, an ordinary user (not the Factory contract and the DAO contract itself) can upgrade (tamper) the code of any DAO contract through the pub fn update() method provided by the Factory contract, which will give Sputnik-DAO platform and All contract projects that rely on the Sputnik-DAO platform bring great security risks.

🪴 Fortunately, when this problem was discovered, the code of this version had not yet been launched on the NEAR mainnet, so there was no loss.

Due to the rapid response of the project party, the vulnerability has been correctly fixed by adding a reasonable whitelist verification mechanism😊

first level title

text

In addition to the vulnerabilities discovered and fixed above, the security of the Sputnik-DAO Factory contract is mainly guaranteed from the following aspects:

None of the following functions modify state variables:

Due to the rapid response of the project party, the vulnerability has been correctly fixed by adding a reasonable whitelist verification mechanism😊

See this Fixing Commit: 518ad1d97614fff4b945aba75b6c8bd2483187a2🔗

BlockSec
作者文库