Closed c4-submissions closed 10 months ago
raymondfam marked the issue as low quality report
raymondfam marked the issue as duplicate of #160
alex-ppg marked the issue as not a duplicate
This exhibit relates to data migration in a hypothetical upgrade scenario that involves off-chain code. Such issues are generally out-of-scope.
alex-ppg marked the issue as unsatisfactory: Invalid
alex-ppg marked the issue as unsatisfactory: Out of scope
Lines of code
https://github.com/code-423n4/2023-10-brahma/blob/dd0b41031b199a0aa214e50758943712f9f574a0/contracts/src/core/ExecutorPlugin.sol#L58 https://github.com/code-423n4/2023-10-brahma/blob/dd0b41031b199a0aa214e50758943712f9f574a0/contracts/src/core/SafeDeployer.sol#L45
Vulnerability details
Impact
According to this document, the AddressProvider contract manages and updates addresses of authorized contracts and registries within the system. If security vulnerabilities are discovered or functional upgrades are needed in a contract, the government can deploy a new version of the contract and then use the
setAuthorizedAddress
function to update the contract's address. https://github.com/code-423n4/2023-10-brahma/blob/dd0b41031b199a0aa214e50758943712f9f574a0/contracts/src/core/AddressProvider.sol#L77-L90It should be noted that, in addition to deploying a new version of the contract, data from the old contract needs to be migrated to the new contract; otherwise, the new contract won't function properly. Brahma does not provide a method for data migration.
The method I can think of is to use
eth_getLogs
to query the contract's log information, retrieve the contract data from the logs, and then migrate it to the new version of the contract. Here is an example:The data to be migrated is the
commitments
. The PolicyRegistry contract defines an event:event UpdatedPolicyCommit(address indexed account, bytes32 policyCommit, bytes32 oldPolicyCommit);
. When a policy commit is added, this event is emitted. By usingeth_getLogs
, you can query all policy commits and then migrate the data to the new version of the contract. https://github.com/code-423n4/2023-10-brahma/blob/dd0b41031b199a0aa214e50758943712f9f574a0/contracts/src/core/registries/PolicyRegistry.sol#L66-L69If this method is used to migrate data, it requires defining an event for all data. When adding or removing data, emit an event. However, Brahma has not defined events for
executorNonce
in theExecutorPlugin
contract andownerSafeCount
in theSafeDeployer
contract. If these two contracts need an upgrade, data cannot be migrated to the new version.To emphasize further, utilizing
eth_getLogs
to fetch data for migration is not an ideal approach. This is because it requires querying the modification history of the data each time to determine its final value. Such a process can be complex and prone to errors.Taking
commitments
as an example, the reason why its value cannot be directly obtained is becausecommitments
is a mapping data type, and it's not possible to retrieve allaccount
directly. To address this issue, you can add an arrayaddress[] public accounts
; to keep track of all accounts. This way, you can then iterate through the array of accounts to retrieve the values ofcommitments
.Proof of Concept
The following is a snippet of test code. In this test, a console is deployed, and
ownerSafeCount
goes to 1 after the deploying. ThenSafeDeployer
is upgraded to a new version. After this upgrading, theownerSafeCount
turns to 0.Tools Used
Foundry
Recommended Mitigation Steps
Set events for
executorNonce
andownerSafeCount
, emitting an event whenever these values change. or Add an array for every mapping data. or Use proxy, so data migration is not need during contract upgrading.Assessed type
Context