我无法理解池部署使用通过插槽传递变量。它是如何工作的,为什么开发人员选择这种初始化方式(猜测它更便宜)?
池合同片段(简化):
contract UniswapV3Pool {
address public immutable override factory;
address public immutable override token0;
address public immutable override token1;
uint24 public immutable override fee;
int24 public immutable override tickSpacing;
uint128 public immutable override maxLiquidityPerTick;
constructor() {
int24 _tickSpacing;
(factory, token0, token1, fee, _tickSpacing) = IUniswapV3PoolDeployer(msg.sender).parameters();
}
}和Deployer合同:
contract UniswapV3PoolDeployer is IUniswapV3PoolDeployer {
struct Parameters {
address factory;
address token0;
address token1;
uint24 fee;
int24 tickSpacing;
}
Parameters public override parameters;
/// @dev Deploys a pool with the given parameters by transiently setting the parameters storage slot and then
/// clearing it after deploying the pool.
function deploy(
address factory,
address token0,
address token1,
uint24 fee,
int24 tickSpacing
) internal returns (address pool) {
parameters = Parameters({factory: factory, token0: token0, token1: token1, fee: fee, tickSpacing: tickSpacing});
pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}());
delete parameters;
}
}Solidity =0.7.6 (在代码片段中)契约:https://github.com/Uniswap/v3-core/tree/main/contracts
发布于 2022-01-31 09:39:36
参数在本例中由IUniswapV3PoolDeployer.parameters()调用https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/IUniswapV3PoolDeployer.sol传递。
interface IUniswapV3PoolDeployer {
function parameters()
external
view
returns (
address factory,
address token0,
address token1,
uint24 fee,
int24 tickSpacing
);
}函数调用发生在UniswapV3Pool构造函数中
https://github.com/Uniswap/v3-core/blob/main/contracts/UniswapV3Pool.sol#L119
constructor() {
int24 _tickSpacing;
(factory, token0, token1, fee, _tickSpacing) = IUniswapV3PoolDeployer(msg.sender).parameters();
tickSpacing = _tickSpacing;
maxLiquidityPerTick = Tick.tickSpacingToMaxLiquidityPerTick(_tickSpacing);
}这个调用在UniswapV3PoolDeployer中没有直接的D7实现,因为:
The compiler automatically creates getter functions for all public state variables.https://docs.soliditylang.org/en/v0.8.11/contracts.html#getter-functions
Answering我问题的另一部分
Uniswap通过这种方式部署新的池,因为:
This is used to avoid having constructor arguments in the pool contract,
which results in the init code hash of the pool being constant
allowing the CREATE2 address of the pool to be cheaply computed on-chain.https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/IUniswapV3PoolDeployer.sol#L6
并且我认为它在.deploy()池配置器函数中的参数删除上节省了一些气体。
关于CREATE2的更多信息:https://docs.openzeppelin.com/cli/2.8/deploying-with-create2
https://ethereum.stackexchange.com/questions/120272
复制相似问题