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": []
}
}}
Submitted on: 2025-10-30 14:31:36
Comments
Log in to comment.
No comments yet.