AddressUtils

Description:

Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "Usdc.sol": {
      "content": "pragma solidity ^0.4.24;\r
\r
// Libreria per indirizzi\r
library AddressUtils {\r
    function isContract(address addr) internal view returns (bool) {\r
        uint256 size;\r
        assembly { size := extcodesize(addr) }\r
        return size > 0;\r
    }\r
}\r
\r
// Proxy base\r
contract Proxy {\r
    function () payable external { _fallback(); }\r
    function _implementation() internal view returns (address);\r
    function _delegate(address implementation) internal {\r
        assembly {\r
            calldatacopy(0, 0, calldatasize)\r
            let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)\r
            returndatacopy(0, 0, returndatasize)\r
            switch result\r
            case 0 { revert(0, returndatasize) }\r
            default { return(0, returndatasize) }\r
        }\r
    }\r
    function _willFallback() internal { }\r
    function _fallback() internal { _willFallback(); _delegate(_implementation()); }\r
}\r
\r
// Proxy aggiornabile\r
contract UpgradeabilityProxy is Proxy {\r
    event Upgraded(address implementation);\r
    bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;\r
\r
    constructor(address _implementation) public {\r
        assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation"));\r
        _setImplementation(_implementation);\r
    }\r
\r
    function _implementation() internal view returns (address impl) {\r
        bytes32 slot = IMPLEMENTATION_SLOT;\r
        assembly { impl := sload(slot) }\r
    }\r
\r
    function _upgradeTo(address newImplementation) internal {\r
        _setImplementation(newImplementation);\r
        emit Upgraded(newImplementation);\r
    }\r
\r
    function _setImplementation(address newImplementation) private {\r
        require(AddressUtils.isContract(newImplementation), "Non è un contratto");\r
        bytes32 slot = IMPLEMENTATION_SLOT;\r
        assembly { sstore(slot, newImplementation) }\r
    }\r
}\r
\r
// Proxy con admin\r
contract AdminUpgradeabilityProxy is UpgradeabilityProxy {\r
    event AdminChanged(address previousAdmin, address newAdmin);\r
    bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b;\r
\r
    modifier ifAdmin() {\r
        if (msg.sender == _admin()) { _; } else { _fallback(); }\r
    }\r
\r
    constructor(address _implementation) UpgradeabilityProxy(_implementation) public {\r
        assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));\r
        _setAdmin(msg.sender);\r
    }\r
\r
    function admin() external view ifAdmin returns (address) { return _admin(); }\r
    function implementation() external view ifAdmin returns (address) { return _implementation(); }\r
    function changeAdmin(address newAdmin) external ifAdmin {\r
        require(newAdmin != address(0), "Zero address non valido");\r
        emit AdminChanged(_admin(), newAdmin);\r
        _setAdmin(newAdmin);\r
    }\r
    function upgradeTo(address newImplementation) external ifAdmin { _upgradeTo(newImplementation); }\r
    function upgradeToAndCall(address newImplementation, bytes data) payable external ifAdmin {\r
        _upgradeTo(newImplementation);\r
        require(address(this).call.value(msg.value)(data));\r
    }\r
\r
    function _admin() internal view returns (address adm) {\r
        bytes32 slot = ADMIN_SLOT;\r
        assembly { adm := sload(slot) }\r
    }\r
\r
    function _setAdmin(address newAdmin) internal {\r
        bytes32 slot = ADMIN_SLOT;\r
        assembly { sstore(slot, newAdmin) }\r
    }\r
\r
    function _willFallback() internal {\r
        require(msg.sender != _admin(), "Admin non può usare fallback");\r
        super._willFallback();\r
    }\r
}\r
\r
// Implementazione ERC20 con mint\r
contract FiatTokenImplementation {\r
    string public name = "FiatToken";\r
    string public symbol = "FTK";\r
    uint8 public decimals = 18;\r
    uint256 public totalSupply;\r
\r
    mapping(address => uint256) balances;\r
    mapping(address => mapping(address => uint256)) allowed;\r
\r
    address public owner;\r
\r
    constructor() public { owner = msg.sender; }\r
\r
    modifier onlyOwner() { require(msg.sender == owner, "Solo owner"); _; }\r
\r
    function balanceOf(address who) public view returns (uint256) { return balances[who]; }\r
\r
    function transfer(address to, uint256 value) public returns (bool) {\r
        require(balances[msg.sender] >= value, "Saldo insufficiente");\r
        balances[msg.sender] -= value;\r
        balances[to] += value;\r
        return true;\r
    }\r
\r
    function mint(address to, uint256 value) public onlyOwner returns (bool) {\r
        totalSupply += value;\r
        balances[to] += value;\r
        return true;\r
    }\r
}\r
\r
// Proxy finale per deploy\r
contract FiatTokenProxy is AdminUpgradeabilityProxy {\r
    constructor(address _implementation) public AdminUpgradeabilityProxy(_implementation) { }\r
}\r
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
Proxy, Upgradeable, Factory|addr:0x97e764dbd2f05b09190749fd9ff72de0ba4a39fa|verified:true|block:23690018|tx:0xb2fc163e76ca0cd6c23aab0d5962cf7127eb9ab991d6dd4e73f174ebd9d83e43|first_check:1761831093

Submitted on: 2025-10-30 14:31:36

Comments

Log in to comment.

No comments yet.