mirror of
https://github.com/serai-dex/serai.git
synced 2025-04-22 22:18:15 +00:00
Check the escaped to address has code set
Document choice not to use a confirmation flow there as well.
This commit is contained in:
parent
c8f3a32fdf
commit
373e794d2c
2 changed files with 33 additions and 13 deletions
processor/ethereum/router/contracts
|
@ -34,11 +34,11 @@ interface IRouterWithoutCollisions {
|
|||
* An `OutInstruction` is considered as having succeeded if the call transferring ETH doesn't
|
||||
* fail, the ERC20 transfer doesn't fail, and any executed code doesn't revert.
|
||||
*/
|
||||
event Executed(uint256 indexed nonce, bytes32 indexed messageHash, bytes results);
|
||||
event Batch(uint256 indexed nonce, bytes32 indexed messageHash, bytes results);
|
||||
|
||||
/// @notice Emitted when `escapeHatch` is invoked
|
||||
/// @param escapeTo The address to escape to
|
||||
event EscapeHatch(address indexed escapeTo);
|
||||
event EscapeHatch(uint256 indexed nonce, address indexed escapeTo);
|
||||
|
||||
/// @notice Emitted when coins escape through the escape hatch
|
||||
/// @param coin The coin which escaped
|
||||
|
@ -122,7 +122,10 @@ interface IRouter is IRouterWithoutCollisions {
|
|||
}
|
||||
|
||||
/// @title The type of destination
|
||||
/// @dev A destination is either an address or a blob of code to deploy and call
|
||||
/**
|
||||
* @dev A destination is either an ABI-encoded address or an ABI-encoded `CodeDestination`
|
||||
* containing code to deploy (invoking its constructor).
|
||||
*/
|
||||
enum DestinationType {
|
||||
Address,
|
||||
Code
|
||||
|
|
|
@ -25,13 +25,12 @@ import "IRouter.sol";
|
|||
/// @author Luke Parker <lukeparker@serai.exchange>
|
||||
/// @notice Intakes coins for the Serai network and handles relaying batches of transfers out
|
||||
contract Router is IRouterWithoutCollisions {
|
||||
/// @dev The code hash for a non-empty account without code
|
||||
bytes32 constant ACCOUNT_WITHOUT_CODE_CODEHASH = keccak256("");
|
||||
|
||||
/// @dev The address in transient storage used for the reentrancy guard
|
||||
bytes32 constant EXECUTE_REENTRANCY_GUARD_SLOT = bytes32(
|
||||
/*
|
||||
keccak256("ReentrancyGuard Router.execute") - 1
|
||||
*/
|
||||
0xcf124a063de1614fedbd6b47187f98bf8873a1ae83da5c179a5881162f5b2401
|
||||
);
|
||||
bytes32 constant EXECUTE_REENTRANCY_GUARD_SLOT =
|
||||
bytes32(uint256(keccak256("ReentrancyGuard Router.execute")) - 1);
|
||||
|
||||
/**
|
||||
* @dev The next nonce used to determine the address of contracts deployed with CREATE. This is
|
||||
|
@ -509,11 +508,11 @@ contract Router is IRouterWithoutCollisions {
|
|||
}
|
||||
|
||||
/*
|
||||
Emit execution with the status of all included events.
|
||||
Emit batch execution with the status of all included events.
|
||||
|
||||
This is an effect after interactions yet we have a reentrancy guard making this safe.
|
||||
*/
|
||||
emit Executed(nonceUsed, message, results);
|
||||
emit Batch(nonceUsed, message, results);
|
||||
|
||||
// Transfer the fee to the relayer
|
||||
transferOut(msg.sender, coin, fee);
|
||||
|
@ -529,13 +528,31 @@ contract Router is IRouterWithoutCollisions {
|
|||
// @param escapeTo The address to escape to
|
||||
function escapeHatchDCDD91CC() external {
|
||||
// Verify the signature
|
||||
(, bytes memory args,) = verifySignature(_seraiKey);
|
||||
(uint256 nonceUsed, bytes memory args,) = verifySignature(_seraiKey);
|
||||
|
||||
(,, address escapeTo) = abi.decode(args, (bytes32, bytes32, address));
|
||||
|
||||
if (escapeTo == address(0)) {
|
||||
revert InvalidEscapeAddress();
|
||||
}
|
||||
|
||||
/*
|
||||
We could define the escape hatch as having its own confirmation flow, as new keys do, but new
|
||||
contracts don't face all of the cryptographic concerns faced by new keys. New contracts also
|
||||
would presumably be moved to after strict review, making the chance of specifying the wrong
|
||||
contract incredibly unlikely.
|
||||
|
||||
The only check performed accordingly (with no confirmation flow) is that the new contract is
|
||||
in fact a contract. This is done to confirm the contract was successfully deployed on this
|
||||
blockchain.
|
||||
*/
|
||||
{
|
||||
bytes32 codehash = escapeTo.codehash;
|
||||
if ((codehash == bytes32(0)) || (codehash == ACCOUNT_WITHOUT_CODE_CODEHASH)) {
|
||||
revert InvalidEscapeAddress();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We want to define the escape hatch so coins here now, and latently received, can be forwarded.
|
||||
If the last Serai key set could update the escape hatch, they could siphon off latently
|
||||
|
@ -546,7 +563,7 @@ contract Router is IRouterWithoutCollisions {
|
|||
}
|
||||
|
||||
_escapedTo = escapeTo;
|
||||
emit EscapeHatch(escapeTo);
|
||||
emit EscapeHatch(nonceUsed, escapeTo);
|
||||
}
|
||||
|
||||
/// @notice Escape coins after the escape hatch has been invoked
|
||||
|
|
Loading…
Reference in a new issue