Address Contract Partially Verified
Address
0xfc00C80b0000007F73004edB00094caD80626d8D
Balance
0 ETH
Nonce
19085
Code Size
2440 bytes
Creator
0x00000000...9497 at tx 0x60b5ab98...2bdd27
Indexed Transactions
0
Contract Bytecode
2440 bytes
0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063285e7bfd1461003b578063e8dd05f21461007d575b600080fd5b6100616004803603602081101561005157600080fd5b50356001600160a01b03166100a3565b604080516001600160a01b039092168252519081900360200190f35b6100616004803603602081101561009357600080fd5b50356001600160a01b0316610140565b604080516001600160a01b0383166024808301919091528251808303909101815260449091019091526020810180516001600160e01b031663189acdbd60e31b1790526000906100f281610196565b604080516001600160a01b0380841682528616602082015281519294507f6e60d84846384a1994833ed675b0a0f76bef64943304debf6e42a9706d1a7dd7929081900390910190a150919050565b604080516001600160a01b0383166024808301919091528251808303909101815260449091019091526020810180516001600160e01b031663189acdbd60e31b17905260009061018f81610324565b9392505050565b60006060604051806020016101aa90610504565b6020820181038252601f19601f82011660405250836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156101ff5781810151838201526020016101e7565b50505050905090810190601f16801561022c5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040526040516020018083805190602001908083835b602083106102725780518252601f199092019160209182019101610253565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106102ba5780518252601f19909201916020918201910161029b565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905060006102fc82610490565b50905081602001825182818334f594508461031b573d6000803e3d6000fd5b50505050919050565b600060606040518060200161033890610504565b6020820181038252601f19601f82011660405250836040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561038d578181015183820152602001610375565b50505050905090810190601f1680156103ba5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040526040516020018083805190602001908083835b602083106104005780518252601f1990920191602091820191016103e1565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106104485780518252601f199092019160209182019101610429565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905061048881610490565b949350505050565b805160208201206000908190815b50604080516001600160f81b03196020808301919091523060601b602183015260358201869052605580830185905283518084039091018152607590920190925280519101209150813b806104f2576104fd565b60019093019261049e565b5050915091565b610442806105128339019056fe60806040526040516104423803806104428339818101604052602081101561002657600080fd5b810190808051604051939291908464010000000082111561004657600080fd5b90830190602082018581111561005b57600080fd5b825164010000000081118282018810171561007557600080fd5b82525081516020918201929091019080838360005b838110156100a257818101518382015260200161008a565b50505050905090810190601f1680156100cf5780820380516001836020036101000a031916815260200191505b5060405250505060006100e661019e60201b60201c565b6001600160a01b0316826040518082805190602001908083835b6020831061011f5780518252601f199092019160209182019101610100565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461017f576040519150601f19603f3d011682016040523d82523d6000602084013e610184565b606091505b5050905080610197573d6000803e3d6000fd5b50506102be565b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d80600081146101f0576040519150601f19603f3d011682016040523d82523d6000602084013e6101f5565b606091505b509150915081819061029f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026457818101518382015260200161024c565b50505050905090810190601f1680156102915780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508080602001905160208110156102b557600080fd5b50519392505050565b610175806102cd6000396000f3fe608060405261001461000f610016565b61011c565b005b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d8060008114610068576040519150601f19603f3d011682016040523d82523d6000602084013e61006d565b606091505b50915091508181906100fd5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156100c25781810151838201526020016100aa565b50505050905090810190601f1680156100ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5080806020019051602081101561011357600080fd5b50519392505050565b3660008037600080366000845af43d6000803e80801561013b573d6000f35b3d6000fdfea265627a7a7231582020202020202055706772616465426561636f6e50726f7879563120202020202064736f6c634300050b0032a265627a7a72315820202020446861726d61536d61727457616c6c6574466163746f7279312020202064736f6c634300050b0032
Verified Source Code Partial Match
Compiler: v0.5.11+commit.c082d0b4
EVM: petersburg
Optimization: Yes (200 runs)
DharmaSmartWalletFactoryV1.sol 278 lines
pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg
interface DharmaSmartWalletFactoryV1Interface {
// Fires an event when a new smart wallet is deployed and initialized.
event SmartWalletDeployed(address wallet, address userSigningKey);
function newSmartWallet(
address userSigningKey
) external returns (address wallet);
function getNextSmartWallet(
address userSigningKey
) external view returns (address wallet);
}
interface DharmaSmartWalletInitializer {
function initialize(address userSigningKey) external;
}
/**
* @title UpgradeBeaconProxyV1
* @author 0age
* @notice This contract delegates all logic, including initialization, to an
* implementation contract specified by a hard-coded "upgrade beacon" contract.
* Note that this implementation can be reduced in size by stripping out the
* metadata hash, or even more significantly by using a minimal upgrade beacon
* proxy implemented using raw EVM opcodes.
*/
contract UpgradeBeaconProxyV1 {
// Set upgrade beacon address as a constant (i.e. not in contract storage).
address private constant _UPGRADE_BEACON = address(
0x000000000026750c571ce882B17016557279ADaa
);
/**
* @notice In the constructor, perform initialization via delegatecall to the
* implementation set on the upgrade beacon, supplying initialization calldata
* as a constructor argument. The deployment will revert and pass along the
* revert reason in the event that this initialization delegatecall reverts.
* @param initializationCalldata Calldata to supply when performing the
* initialization delegatecall.
*/
constructor(bytes memory initializationCalldata) public payable {
// Delegatecall into the implementation, supplying initialization calldata.
(bool ok, ) = _implementation().delegatecall(initializationCalldata);
// Revert and include revert data if delegatecall to implementation reverts.
if (!ok) {
assembly {
returndatacopy(0, 0, returndatasize)
revert(0, returndatasize)
}
}
}
/**
* @notice In the fallback, delegate execution to the implementation set on
* the upgrade beacon.
*/
function () external payable {
// Delegate execution to implementation contract provided by upgrade beacon.
_delegate(_implementation());
}
/**
* @notice Private view function to get the current implementation from the
* upgrade beacon. This is accomplished via a staticcall to the beacon with no
* data, and the beacon will return an abi-encoded implementation address.
* @return implementation Address of the implementation.
*/
function _implementation() private view returns (address implementation) {
// Get the current implementation address from the upgrade beacon.
(bool ok, bytes memory returnData) = _UPGRADE_BEACON.staticcall("");
// Revert and pass along revert message if call to upgrade beacon reverts.
require(ok, string(returnData));
// Set the implementation to the address returned from the upgrade beacon.
implementation = abi.decode(returnData, (address));
}
/**
* @notice Private function that delegates execution to an implementation
* contract. This is a low level function that doesn't return to its internal
* call site. It will return whatever is returned by the implementation to the
* external caller, reverting and returning the revert data if implementation
* reverts.
* @param implementation Address to delegate.
*/
function _delegate(address implementation) private {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize)
// Delegatecall to the implementation, supplying calldata and gas.
// Out and outsize are set to zero - instead, use the return buffer.
let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
// Copy the returned data from the return buffer.
returndatacopy(0, 0, returndatasize)
switch result
// Delegatecall returns 0 on error.
case 0 { revert(0, returndatasize) }
default { return(0, returndatasize) }
}
}
}
/**
* @title DharmaSmartWalletFactoryV1
* @author 0age
* @notice This contract deploys new Dharma Smart Wallet instances as "Upgrade
* Beacon" proxies that reference a shared implementation contract specified by
* the Dharma Upgrade Beacon contract.
*/
contract DharmaSmartWalletFactoryV1 is DharmaSmartWalletFactoryV1Interface {
// Use Dharma Smart Wallet initializer to construct initialization calldata.
DharmaSmartWalletInitializer private _INITIALIZER;
/**
* @notice Deploy a new smart wallet address using the provided user signing
* key.
* @param userSigningKey address The user signing key, supplied as a
* constructor argument.
* @return The address of the new smart wallet.
*/
function newSmartWallet(
address userSigningKey
) external returns (address wallet) {
// Get initialization calldata from initialize selector & user signing key.
bytes memory initializationCalldata = abi.encodeWithSelector(
_INITIALIZER.initialize.selector,
userSigningKey
);
// Initialize and deploy new user smart wallet as an Upgrade Beacon proxy.
wallet = _deployUpgradeBeaconProxyInstance(initializationCalldata);
// Emit an event to signal the creation of the new smart wallet.
emit SmartWalletDeployed(wallet, userSigningKey);
}
/**
* @notice View function to find the address of the next smart wallet address
* that will be deployed for a given user signing key. Note that a new value
* will be returned if a particular user signing key has been used before.
* @param userSigningKey address The user signing key, supplied as a
* constructor argument.
* @return The future address of the next smart wallet.
*/
function getNextSmartWallet(
address userSigningKey
) external view returns (address wallet) {
// Get initialization calldata from initialize selector & user signing key.
bytes memory initializationCalldata = abi.encodeWithSelector(
_INITIALIZER.initialize.selector,
userSigningKey
);
// Determine the user's smart wallet address based on the user signing key.
wallet = _computeNextAddress(initializationCalldata);
}
/**
* @notice Private function to deploy an upgrade beacon proxy via `CREATE2`.
* @param initializationCalldata bytes The calldata that will be supplied to
* the `DELEGATECALL` from the deployed contract to the implementation set on
* the upgrade beacon during contract creation.
* @return The address of the newly-deployed upgrade beacon proxy.
*/
function _deployUpgradeBeaconProxyInstance(
bytes memory initializationCalldata
) private returns (address upgradeBeaconProxyInstance) {
// Place creation code and constructor args of new proxy instance in memory.
bytes memory initCode = abi.encodePacked(
type(UpgradeBeaconProxyV1).creationCode,
abi.encode(initializationCalldata)
);
// Get salt to use during deployment using the supplied initialization code.
(uint256 salt, ) = _getSaltAndTarget(initCode);
// Deploy the new upgrade beacon proxy contract using `CREATE2`.
assembly {
let encoded_data := add(0x20, initCode) // load initialization code.
let encoded_size := mload(initCode) // load the init code's length.
upgradeBeaconProxyInstance := create2( // call `CREATE2` w/ 4 arguments.
callvalue, // forward any supplied endowment.
encoded_data, // pass in initialization code.
encoded_size, // pass in init code's length.
salt // pass in the salt value.
)
// Pass along failure message and revert if contract deployment fails.
if iszero(upgradeBeaconProxyInstance) {
returndatacopy(0, 0, returndatasize)
revert(0, returndatasize)
}
}
}
/**
* @notice Private view function for finding the address of the next upgrade
* beacon proxy that will be deployed, given a particular initialization
* calldata payload.
* @param initializationCalldata bytes The calldata that will be supplied to
* the `DELEGATECALL` from the deployed contract to the implementation set on
* the upgrade beacon during contract creation.
* @return The address of the next upgrade beacon proxy contract with the
* given initialization calldata.
*/
function _computeNextAddress(
bytes memory initializationCalldata
) private view returns (address target) {
// Place creation code and constructor args of the proxy instance in memory.
bytes memory initCode = abi.encodePacked(
type(UpgradeBeaconProxyV1).creationCode,
abi.encode(initializationCalldata)
);
// Get target address using the constructed initialization code.
(, target) = _getSaltAndTarget(initCode);
}
/**
* @notice Private function for determining the salt and the target deployment
* address for the next deployed contract (using `CREATE2`) based on the
* contract creation code.
*/
function _getSaltAndTarget(
bytes memory initCode
) private view returns (uint256 nonce, address target) {
// Get the keccak256 hash of the init code for address derivation.
bytes32 initCodeHash = keccak256(initCode);
// Set the initial nonce to be provided when constructing the salt.
nonce = 0;
// Declare variable for code size of derived address.
uint256 codeSize;
// Loop until an contract deployment address with no code has been found.
while (true) {
target = address( // derive the target deployment address.
uint160( // downcast to match the address type.
uint256( // cast to uint to truncate upper digits.
keccak256( // compute CREATE2 hash using 4 inputs.
abi.encodePacked( // pack all inputs to the hash together.
bytes1(0xff), // pass in the control character.
address(this), // pass in the address of this contract.
nonce, // pass in the salt from above.
initCodeHash // pass in hash of contract creation code.
)
)
)
)
);
// Determine if a contract is already deployed to the target address.
assembly { codeSize := extcodesize(target) }
// Exit the loop if no contract is deployed to the target address.
if (codeSize == 0) {
break;
}
// Otherwise, increment the nonce and derive a new salt.
nonce++;
}
}
}
Read Contract
getNextSmartWallet 0xe8dd05f2 → address
Write Contract 1 functions
These functions modify contract state and require a wallet transaction to execute.
newSmartWallet 0x285e7bfd
address userSigningKey
returns: address
Recent Transactions
No transactions found for this address