I'm trying to test a contract via a proxy, but I don't know how to create an instance of a the contract proxy to call the delegate functions. I'm using typescript, ethers.js with hardhat

The contract Adder have two function called addOne and theCounter which adds one and returns the current value of the counter respectively. how can I call addOne on the proxy contract so the fallback function fires? here is the test I'm trying to write :

import {expect} from 'chai'
import {ethers} from 'hardhat';

describe("Proxy", () => {
  it("should call addOne on delegate", async () => {
    const Delegate = await ethers.getContractFactory("Adder"); 
    const Proxy = await ethers.getContractFactory("Proxy"); 

    let adder = await Delegate.deploy(0);
    let proxy = await Proxy.deploy();

    await adder.deployed();
    await proxy.deployed();

    await proxy.functions.upgradeDelegate(adder.address);

    // TODO : how can I call the function addOne() on proxy???

    expect(await adder.theCounter()).to.equal(1);

this is the code of the proxy:

pragma solidity <0.8.0;

// SPDX-License-Identifier: MIT

contract Proxy {

    address delegate;
    address owner = msg.sender;

    function upgradeDelegate(address newDelegateAddress) public {
        require(msg.sender == owner);
        delegate = newDelegateAddress;

    fallback() external {
        assembly {
            let _target := sload(0)
            calldatacopy(0x0, 0x0, calldatasize())
            let result := delegatecall(gas(), _target, 0x0, calldatasize(), 0x0, 0)
            returndatacopy(0x0, 0x0, returndatasize())
            switch result case 0 {revert(0, 0)} default {return (0, returndatasize())}

and the adder:

pragma solidity <0.8.0;

// SPDX-License-Identifier: MIT

contract Adder {
    uint public counter;

    constructor(uint init) {
        counter = init;

    function addOne() public returns (uint) {
        return counter;

    function theCounter() public view returns (uint) {
        return counter;


1 Answer 1


I used attach to call the implementation functions from my proxy contract:

adder = Delegate.attach(proxy.address) as Delegate
  • I'm going to test this approach , but using the delegate directly and attach the proxy address defeat the purpose of using a proxy, I'm going to create an interface for the delegate (in this case something like IAdder) and test something similar. thanks you.
    – alter
    Commented Apr 5, 2021 at 17:56
  • I'm wondering how it defeats the purpose?
    – emag3m
    Commented May 11, 2021 at 22:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.