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.