pragma solidity >=0.4.21 <0.7.0;
contract MPondProxy {
bytes32 internal constant IMPLEMENTATION_SLOT = bytes32(
uint256(keccak256("eip1967.proxy.implementation")) - 1
);
bytes32 internal constant PROXY_ADMIN_SLOT = bytes32(
uint256(keccak256("eip1967.proxy.admin")) - 1
);
constructor(address contractLogic, address proxyAdmin) public {
// save the code address
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, contractLogic)
}
// save the proxy admin
slot = PROXY_ADMIN_SLOT;
address sender = proxyAdmin;
assembly {
sstore(slot, sender)
}
}
function updateAdmin(address _newAdmin) public {
require(
msg.sender == getAdmin(),
"Only the current admin should be able to new admin"
);
bytes32 slot = PROXY_ADMIN_SLOT;
assembly {
sstore(slot, _newAdmin)
}
}
/// @author Marlin
/// @dev Only admin can update the contract
/// @param _newLogic address is the address of the contract that has to updated to
function updateLogic(address _newLogic) public {
require(
msg.sender == getAdmin(),
"Only Admin should be able to update the contracts"
);
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, _newLogic)
}
}
/// @author Marlin
/// @dev use assembly as contract store slot is manually decided
function getAdmin() internal view returns (address result) {
bytes32 slot = PROXY_ADMIN_SLOT;
assembly {
result := sload(slot)
}
}
/// @author Marlin
/// @dev add functionality to forward the balance as well.
function() external payable {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
let contractLogic := sload(slot)
calldatacopy(0x0, 0x0, calldatasize())
let success := delegatecall(
sub(gas(), 10000),
contractLogic,
0x0,
calldatasize(),
0,
0
)
let retSz := returndatasize()
returndatacopy(0, 0, retSz)
switch success
case 0 {
revert(0, retSz)
}
default {
return(0, retSz)
}
}
}
}
{
"compilationTarget": {
"MPondProxy.sol": "MPondProxy"
},
"evmVersion": "istanbul",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 1000000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"contractLogic","type":"address"},{"internalType":"address","name":"proxyAdmin","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"updateAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newLogic","type":"address"}],"name":"updateLogic","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]