Closed code423n4 closed 2 years ago
Adding comment per warden's request:
I didn't realise until the recent discussion that we should add each occurrence of a bug individually, even if the root cause is the same. It's mentioned in the issue that it works for "each of the deposit boxes". The location of this bug is for each of the following getFunds()
functions:
Kill functionality is temporary and will be removed eventually. It's needed for emergency cases. We hope it would be never used. Typical way to stop SKALE chain - first announce it, then allow to withdraw all funds and only then terminate it.
Given that the finding is based on Admin Privilege, I believe Medium Severity to be more appropriate
Dup of #71
Lines of code
https://github.com/skalenetwork/skale-manager/blob/6827f3c8918424641647f20700232713626be828/contracts/SchainsInternal.sol#L206-L234 https://github.com/skalenetwork/skale-manager/blob/6827f3c8918424641647f20700232713626be828/contracts/SchainsInternal.sol#L522-L524 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/mainnet/SkaleManagerClient.sol#L70-L74 https://github.com/skalenetwork/ima-c4-audit/blob/main/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L196-L209
Vulnerability details
Impact
If the SChain is removed before all the funds are withdrawn from the bridge they will be permanently locked in the bridge.
When a SChain is removed in by the SKALE protocol via the function
SchainsInternal.removeSchain()
the data including theowner
will be deleted. As a result the functionSchainsInternal.getSchainOwner()
will always returnaddress(0)
.Since
getFunds()
in each of the deposit boxes can only be called by the SChain owner (i.e. has the modifieronlySchainOwner
) and the owner address is nowaddress(0)
getFunds()
will always revert. The impact is that any funds associated with this SChain are now locked in the bridge.Proof of Concept
SchainsInternal.sol#L206-L234
SchainsInternal.sol#L522-L524
SkaleManagerClient.sol#L70-L74
DepositBoxERC20.sol#L196-L209
Recommended Mitigation Steps
Consider allowing a fallback option, such as the
DEFAULT_ADMIN_ROLE
of the boxes to be allowed to callgetFunds()
ifSchainsInternal.getSchainOwner()
returnsaddress(0)
and there is still balance in the deposit box for this SChain.