Skip to content

Latest commit

 

History

History
272 lines (224 loc) · 7.59 KB

Proxy.md

File metadata and controls

272 lines (224 loc) · 7.59 KB

Base Proxy contract.

Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/Proxy.sol (Proxy.sol)

View Source: contracts/Proxy/Proxy.sol

↗ Extends: Ownable ↘ Derived Contracts: UpgradableProxy

Proxy

The proxy performs delegated calls to the contract implementation it is pointing to. This way upgradable contracts are possible on blockchain. Delegating proxy contracts are widely used for both upgradeability and gas savings. These proxies rely on a logic contract (also known as implementation contract or master copy) that is called using delegatecall. This allows proxies to keep a persistent state (storage and balance) while the code is delegated to the logic contract. Proxy contract is meant to be inherited and its internal functions _setImplementation and _setOwner to be called when upgrades become neccessary. The loan token (iToken) contract as well as the protocol contract act as proxies, delegating all calls to underlying contracts. Therefore, if you want to interact with them using web3, you need to use the ABIs from the contracts containing the actual logic or the interface contract. ABI for LoanToken contracts: LoanTokenLogicStandard ABI for Protocol contract: ISovryn

Contract Members

Constants & Variables

bytes32 private constant KEY_IMPLEMENTATION;

Events

event ImplementationChanged(address indexed _oldImplementation, address indexed _newImplementation);

Functions


_setImplementation

Set address of the implementation.

function _setImplementation(address _implementation) internal nonpayable

Arguments

Name Type Description
_implementation address Address of the implementation.
Source Code
function _setImplementation(address _implementation) internal {
        require(_implementation != address(0), "Proxy::setImplementation: invalid address");
        emit ImplementationChanged(getImplementation(), _implementation);

        bytes32 key = KEY_IMPLEMENTATION;
        assembly {
            sstore(key, _implementation)
        }
    }

getImplementation

Return address of the implementation.

function getImplementation() public view
returns(_implementation address)
Source Code
function getImplementation() public view returns (address _implementation) {
        bytes32 key = KEY_IMPLEMENTATION;
        assembly {
            _implementation := sload(key)
        }
    }

constructor

Fallback function performs a delegate call to the actual implementation address is pointing this proxy. Returns whatever the implementation call returns.

function () external payable
Source Code
fallback() external payable {
        delegate();
    }

constructor

Fallback function performs a delegate call to the actual implementation address is pointing this proxy. Returns whatever the implementation call returns.

function () external payable
Source Code
receive() external payable {
        delegate();
    }

delegate

function delegate() internal nonpayable
Source Code
function delegate() internal {
        address implementation = getImplementation();
        require(implementation != address(0), "Proxy::(): implementation not found");

        assembly {
            let pointer := mload(0x40)
            calldatacopy(pointer, 0, calldatasize())
            let result := delegatecall(gas(), implementation, pointer, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(pointer, 0, size)

            switch result
            case 0 {
                revert(pointer, size)
            }
            default {
                return(pointer, size)
            }
        }
    }

Contracts