Consider the following Solidity code snippet that deploys a minimal proxy contract using the create opcode. What will be the output of the deployProxy function?
contract ProxyFactory {
address public implementation;
constructor(address _implementation) {
implementation = _implementation;
}
function deployProxy() external returns (address proxy) {
bytes20 targetBytes = bytes20(implementation);
assembly {
let clone := mload(0x40)
mstore(clone, 0x3d602d80600a3d3981f3) // part 1
mstore(add(clone, 0x14), shl(0x60, targetBytes)) // target address
mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf3) // part 2
proxy := create(0, clone, 0x37)
}
require(proxy != address(0), "Create failed");
}
}The create opcode returns the address of the new contract or zero on failure.
The deployProxy function uses inline assembly to deploy a minimal proxy contract that points to the implementation address. The create opcode returns the address of the newly created contract if successful, otherwise zero. The function requires the address to be non-zero, so it returns the proxy address on success.
What is the main purpose of using the minimal proxy (clone) pattern in smart contract development?
Think about how proxies save deployment costs by sharing code.
The minimal proxy pattern deploys small proxy contracts that forward calls to a single implementation contract. This saves gas because the proxy contracts are very small and share the same logic, avoiding full contract redeployment.
Examine the following Solidity assembly snippet intended to deploy a minimal proxy. What error will occur when this code runs?
assembly {
let clone := mload(0x40)
mstore(clone, 0x3d602d80600a3d3981f3)
mstore(add(clone, 0x14), shl(0x60, implementation))
mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf3)
let proxy := create(0, clone, 0x36)
if iszero(proxy) { revert(0, 0) }
}Check the length of the deployed code passed to create.
The minimal proxy bytecode length is 0x37 bytes. Passing 0x36 causes the deployed code to be incomplete, so create fails and returns zero, triggering the revert.
Which option contains the syntax error in this Solidity function that deploys a minimal proxy?
function clone(address implementation) external returns (address proxy) {
bytes20 targetBytes = bytes20(implementation);
assembly {
let clone := mload(0x40)
mstore(clone, 0x3d602d80600a3d3981f3)
mstore(add(clone, 0x14), shl(0x60, targetBytes))
mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf3)
proxy := create(0, clone, 0x37)
}
require(proxy != address(0), "Create failed");
}Remember that let is only valid inside assembly blocks.
The code correctly uses bytes20 conversion outside assembly and let inside assembly. Semicolons are optional after assembly blocks in Solidity. Therefore, no syntax error exists.
A factory contract deploys minimal proxy clones in a loop as follows:
for (uint i = 0; i < 5; i++) {
deployProxy();
}After this loop completes, how many minimal proxy contracts exist on the blockchain?
Each call to deployProxy() creates a new contract.
Each iteration calls deployProxy(), which uses create to deploy a new minimal proxy contract with a unique address. Thus, 5 distinct proxies exist after the loop.