Maximum line length of 80 in Deployer.sol

This commit is contained in:
Luke Parker
2025-01-18 15:22:58 -05:00
parent 0d906363a0
commit f6b52b3fd3

View File

@@ -4,29 +4,30 @@ pragma solidity ^0.8.26;
/* /*
The expected deployment process of Serai's Router is as follows: The expected deployment process of Serai's Router is as follows:
1) A transaction deploying Deployer is made. Then, a deterministic signature is 1) A transaction deploying Deployer is made. Then, a deterministic signature
created such that an account with an unknown private key is the creator of is created such that an account with an unknown private key is the creator
the contract. Anyone can fund this address, and once anyone does, the of the contract. Anyone can fund this address, and once anyone does, the
transaction deploying Deployer can be published by anyone. No other transaction deploying Deployer can be published by anyone. No other
transaction may be made from that account. transaction may be made from that account.
2) Anyone deploys the Router through the Deployer. This uses a sequential nonce 2) Anyone deploys the Router through the Deployer. This uses a sequential
such that meet-in-the-middle attacks, with complexity 2**80, aren't feasible. nonce such that meet-in-the-middle attacks, with complexity 2**80, aren't
While such attacks would still be feasible if the Deployer's address was feasible. While such attacks would still be feasible if the Deployer's
controllable, the usage of a deterministic signature with a NUMS method address was controllable, the usage of a deterministic signature with a
prevents that. NUMS method prevents that.
This doesn't have any denial-of-service risks and will resolve once anyone steps This doesn't have any denial-of-service risks and will resolve once anyone
forward as deployer. This does fail to guarantee an identical address across steps forward as deployer. This does fail to guarantee an identical address
every chain, though it enables letting anyone efficiently ask the Deployer for for the Router across every chain, though it enables anyone to efficiently
the address (with the Deployer having an identical address on every chain). ask the Deployer for the address (with the Deployer having an identical
address on every chain).
Unfortunately, guaranteeing identical addresses aren't feasible. We'd need the Unfortunately, guaranteeing identical addresses for the Router isn't
Deployer contract to use a consistent salt for the Router, yet the Router must feasible. We'd need the Deployer contract to use a consistent salt for the
be deployed with a specific public key for Serai. Since Ethereum isn't able to Router, yet the Router must be deployed with a specific public key for Serai.
determine a valid public key (one the result of a Serai DKG) from a dishonest Since Ethereum isn't able to determine a valid public key (one the result of
public key, we have to allow multiple deployments with Serai being the one to a Serai DKG) from a dishonest public key (one arbitrary), we have to allow
determine which to use. multiple deployments with Serai being the one to determine which to use.
The alternative would be to have a council publish the Serai key on-Ethereum, The alternative would be to have a council publish the Serai key on-Ethereum,
with Serai verifying the published result. This would introduce a DoS risk in with Serai verifying the published result. This would introduce a DoS risk in
@@ -68,15 +69,18 @@ contract Deployer {
/* /*
Check this wasn't prior deployed. Check this wasn't prior deployed.
This is a post-check, not a pre-check (in violation of the CEI pattern). If we used a This is a post-check, not a pre-check (in violation of the CEI pattern).
pre-check, a deployed contract could re-enter the Deployer to deploy the same contract If we used a pre-check, a deployed contract could re-enter the Deployer
multiple times due to the inner call updating state and then the outer call overwriting it. to deploy the same contract multiple times due to the inner call updating
The post-check causes the outer call to error once the inner call updates state. state and then the outer call overwriting it. The post-check causes the
outer call to error once the inner call updates state.
This does mean contract deployment may fail if deployment causes arbitrary execution which This does mean contract deployment may fail if deployment causes
maliciously nests deployment of the being-deployed contract. Such an inner call won't fail, arbitrary execution which maliciously nests deployment of the
yet the outer call would. The usage of a re-entrancy guard would call the inner call to fail being-deployed contract. Such an inner call won't fail, yet the outer
while the outer call succeeds. This is considered so edge-case it isn't worth handling. call would. The usage of a re-entrancy guard would cause the inner call
to fail while the outer call succeeds. This is considered so edge-case it
isn't worth handling.
*/ */
if (deployments[initCodeHash] != address(0)) { if (deployments[initCodeHash] != address(0)) {
revert PriorDeployed(); revert PriorDeployed();