Emergency migration is a process in the protocol which migrates MoneyShelf to MoneyVault in case of any emergency which should respect the Default Framework Architecture as described in the image below
Each Policy (contracts like Laundrette.sol) have their own modules (like MoneyShelf.sol) with kernel.sol overseeing the Policies(Front-Facing Contracts) and modules(Internal-facing contracts)
In the time of an emergency when EmergencyMigration.s.sol is deployed and migrate function is called the MoneyShelf is migrated to MoneyVault but the underlying problem is that in the Front-Facing Laundrette.sol no update is made regarding MoneyVault and the state of contract MoneyShelf.sol is never Migrated to MoneyVault.sol.
An alternate way to install a new module like MoneyVault would be to create a new Policy but none was created which may lead to complete loss of control over funds during Emergency Migration
The current EmergencyMigration.s.sol is an incorrect implementation of EmergencyMigration and it may lead to :
MoneyVault being empty
godFather looses control over MoneyVault since there is no policy to call its functions
All the Funds being stuck in MoneyShelf with no way to retrieve it during Emergency period
Even after migration the Laundrette.sol points to the MoneyShelf.sol as its module and MoneyVault.sol's state is never updated using the Module::INIT() functions and it has no policy to call its functions which can lead to complete loss of control over funds .
A mitigation to consider would be to just DeactivatePolicy pointing to address of Laundrette.sol and ActivatePolicy(re-activate) it again this makes the Laundrette.sol point to MoneyVault.sol but the state of MoneyVault will still be empty as it isn't updated anywhere and requires to be addresses and also the Laundrette.sol has many other functions which are unaccounted for after migration
hence a better solution would be to introduce a new Policy for emergency migration named Emergency.sol,this respects the Default Frame Work Architecture as well as the design needs of the protocol.
Regarding the state migration the actual funds and the details of balances are stored in MoneyShelf.sol which are needed to be migrated to MoneyVault.sol when the module is upgraded,this can be addressed by making use of the kernel.sol's Module::INIT function which is called during the updgrade of the module.
Note: If you don't want to introduce a new policy then you can just implement the changes by ggnoring any lines of code related to the new Emergency contract.
Make the Following changes to mitigate the issue:
We Create a new Policy called Emergency.sol this works same as Laundrette.sol but with only
required functions i.e since deposit is not required during emergency it is removed altogether
In src/policies/ add a new Policy called Emergency.sol with the code below :
Brief Explanation of Changes added below:
We need MoneyShelf's address to be transferred to MoneyVault so that we can migrate the state of MoneyShelf to MoneyVault hence we pass it as an argument to the MoneyVaults constructor.
We change kernel::admin back to godFather and grant the role of moneyshelf to MoneyVault.sol this step if not done then money transfers cannot be done i.e godFather cannot withdraw from moneyVault
EmergencyTransfer is the new function which we will add in further steps in MoneyShelf.sol to take care of state changes i.e funds stored in it
We activate a new Policy called i.e Emergency.sol
The EmergencyMigration::migrate now returns MoneyVault and Emergency types
EmergencyMigration.s.sol needs to be modified in this way
This is the new EmergencyTransfer function in MoneyShelf.sol which can be called only by godFather and transfers all the money stored in MoneyShelf to address specified(MoneyVault) by godFather
Add the following function in MoneyShelf.sol
In Shelf.sol we add a few Variables to track the accounts added to the mapping bank and migrate them to MoneyVault when an emergency situation happens
(Note that variables have been declared public for ease of use here, they can be made private which requires adding getter functions to read thir state )
Make the following changes in Shelf.sol (required for state transfer from MoneyShelf to MoneyVault)
Now when even the module MoneyShelf is upgraded to MoneyVault the INIT function is triggered which transfers the state of the MoneyShelf to MoneyVault , we transfer the actual funds in EmergencyMigration::migrate by calling the EmergencyTransfer function of MoneyShelf with the address of moneyVault
Make the following changes in MoneyVault.sol
Now finally add the following test to EmergencyMigration.t.sol and run it
(if any errors show up it is because we added new args to migrate function ,make changes accordingly in other tests or comment them out)
Godfather can add the role manually
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.