ethers#BytesLike TypeScript Examples

The following examples show how to use ethers#BytesLike. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: sign-utils.ts    From shoyu with MIT License 7 votes vote down vote up
getDigest = async (
    provider: any,
    name: string,   // name is deprecated
    contractAddress: string,
    hash: BytesLike
): Promise<string> => {
    return keccak256(
        solidityPack(
            ["bytes1", "bytes1", "bytes32", "bytes32"],
            ["0x19", "0x01", await domainSeparator(provider, name, contractAddress), hash]
        )
    );
}
Example #2
Source File: transfer.ts    From hubble-contracts with MIT License 6 votes vote down vote up
constructor(
        public stateRoot: BytesLike,
        public accountRoot: BytesLike,
        public signature: solG1,
        public feeReceiver: BigNumber,
        public txs: BytesLike
    ) {
        super(stateRoot);
    }
Example #3
Source File: pancakeswap-router-contract.factory.ts    From simple-pancakeswap-sdk with MIT License 6 votes vote down vote up
public removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    token: string,
    liquidity: BigNumberish,
    amountTokenMin: BigNumberish,
    amountETHMin: BigNumberish,
    to: string,
    deadline: BigNumberish,
    approveMax: boolean,
    v: BigNumberish,
    r: BytesLike,
    s: BytesLike
  ): string {
    return this._pancakeswapRouterContract.interface.encodeFunctionData(
      'removeLiquidityETHWithPermitSupportingFeeOnTransferTokens',
      [
        token,
        liquidity,
        amountTokenMin,
        amountETHMin,
        to,
        deadline,
        approveMax,
        v,
        r,
        s,
      ]
    );
  }
Example #4
Source File: UpgradeabilityProxy__factory.ts    From commonwealth with GNU General Public License v3.0 6 votes vote down vote up
deploy(
    _logic: string,
    _data: BytesLike,
    overrides?: PayableOverrides & { from?: string | Promise<string> }
  ): Promise<UpgradeabilityProxy> {
    return super.deploy(
      _logic,
      _data,
      overrides || {}
    ) as Promise<UpgradeabilityProxy>;
  }
Example #5
Source File: uniswap-router-contract.factory.v2.ts    From simple-uniswap-sdk with MIT License 6 votes vote down vote up
public removeLiquidityETHWithPermit(
    token: string,
    liquidity: BigNumberish,
    amountTokenMin: BigNumberish,
    amountETHMin: BigNumberish,
    to: string,
    deadline: BigNumberish,
    approveMax: boolean,
    v: BigNumberish,
    r: BytesLike,
    s: BytesLike
  ): string {
    return this._uniswapRouterContract.interface.encodeFunctionData(
      'removeLiquidityETHWithPermit',
      [
        token,
        liquidity,
        amountTokenMin,
        amountETHMin,
        to,
        deadline,
        approveMax,
        v,
        r,
        s,
      ]
    );
  }
Example #6
Source File: web3.wallet-provider.ts    From etherspot-sdk with MIT License 6 votes vote down vote up
async signMessage(message: BytesLike): Promise<string> {
    return this.sendRequest(
      'personal_sign',
      [
        this.address, //
        toHex(message),
      ],
      this.address,
    );
  }
Example #7
Source File: uniswap-router-contract.factory.v2.ts    From simple-uniswap-sdk with MIT License 6 votes vote down vote up
public removeLiquidityWithPermit(
    tokenA: string,
    tokenB: string,
    liquidity: BigNumberish,
    amountAMin: BigNumberish,
    amountBMin: BigNumberish,
    to: string,
    deadline: BigNumberish,
    approveMax: boolean,
    v: BigNumberish,
    r: BytesLike,
    s: BytesLike
  ): string {
    return this._uniswapRouterContract.interface.encodeFunctionData(
      'removeLiquidityWithPermit',
      [
        tokenA,
        tokenB,
        liquidity,
        amountAMin,
        amountBMin,
        to,
        deadline,
        approveMax,
        v,
        r,
        s,
      ]
    );
  }
Example #8
Source File: sign-utils.ts    From shoyu with MIT License 6 votes vote down vote up
signAsk = async (
    provider: any,
    exchangeName: string, //deprecated
    exchangeAddress: string,
    signer: ethers.Wallet,
    proxy: string,
    token: string,
    tokenId: BigNumberish,
    amount: BigNumberish,
    strategy: string,
    currency: string,
    recipient: string,
    deadline: BigNumberish,
    params: BytesLike
) => {
    const hash = getHash(
        ["bytes32", "address", "address", "address", "uint256", "uint256", "address", "address", "address", "uint256", "bytes32"],
        [
            ASK_TYPEHASH,
            signer.address,
            proxy,
            token,
            tokenId,
            amount,
            strategy,
            currency,
            recipient,
            deadline,
            keccak256(params),
        ]
    );
    const digest = await getDigest(provider, exchangeAddress.toLowerCase(), exchangeAddress, hash);
    const sig = sign(digest, signer);
    const order: AskOrder = {
        signer: signer.address,
        proxy,
        token,
        tokenId,
        amount,
        strategy,
        currency,
        recipient,
        deadline,
        params,
        v: sig.v,
        r: sig.r,
        s: sig.s,
    };
    return { hash, digest, sig, order };
}
Example #9
Source File: to-hex.ts    From etherspot-sdk with MIT License 6 votes vote down vote up
/**
 * @ignore
 */
export function toHex(data: BytesLike): string {
  let result: string = null;

  if (data !== null) {
    switch (typeof data) {
      case 'string':
        if (isHex(data)) {
          result = data;
        } else {
          result = utils.hexlify(utils.toUtf8Bytes(data));
        }
        break;

      case 'object':
        try {
          result = utils.hexlify(data as any);
        } catch (err) {
          result = null;
        }
        break;
    }
  }

  if (!result) {
    throw new Error('invalid hex data');
  }

  return result;
}
Example #10
Source File: transfer.ts    From hubble-contracts with MIT License 6 votes vote down vote up
static fromTxs(
        txs: TransferOffchainTx[],
        stateRoot: BytesLike,
        accountRoot: BytesLike,
        feeReceiver: BigNumber
    ) {
        const signature = getAggregateSig(txs);
        const compressedTx = compress(txs);
        return new this(
            stateRoot,
            accountRoot,
            signature,
            feeReceiver,
            compressedTx
        );
    }
Example #11
Source File: BatchTradeExtensionAPI.ts    From set.js with Apache License 2.0 6 votes vote down vote up
/**
   * Generates BatchTradeExtension initialize call bytecode to be passed as an element in the  `initializeBytecode`
   * array for the DelegatedManagerFactory's `initializeAsync` method.
   *
   * @param delegatedManagerAddress      Instance of deployed DelegatedManager to initialize the BatchTradeExtension for
   *
   * @return                             Initialization bytecode
   */
  public getBatchTradeExtensionInitializationBytecode(
    delegatedManagerAddress: Address
  ): BytesLike {
    this.assert.schema.isValidAddress('delegatedManagerAddress', delegatedManagerAddress);

    const extensionInterface = new EthersUtils.Interface(BatchTradeExtension__factory.abi);
    return extensionInterface.encodeFunctionData('initializeExtension', [ delegatedManagerAddress ]);
  }
Example #12
Source File: commitments.ts    From hubble-contracts with MIT License 6 votes vote down vote up
constructor(
        public stateRoot: BytesLike,
        public accountRoot: BytesLike,
        public signature: solG1,
        public feeReceiver: BigNumberish,
        public txs: BytesLike
    ) {
        super(stateRoot);
    }
Example #13
Source File: BatchTradeExtensionAPI.ts    From set.js with Apache License 2.0 6 votes vote down vote up
/**
   * Generates `moduleAndExtensionInitialization` bytecode to be passed as an element in the  `initializeBytecode`
   * array for the `initializeAsync` method.
   *
   * @param setTokenAddress              Instance of deployed setToken to initialize the TradeModule for
   *
   * @return                             Initialization bytecode
   */
  public getTradeModuleAndExtensionInitializationBytecode(delegatedManagerAddress: Address): BytesLike {
    this.assert.schema.isValidAddress('delegatedManagerAddress', delegatedManagerAddress);

    const extensionInterface = new EthersUtils.Interface(BatchTradeExtension__factory.abi);
    return extensionInterface.encodeFunctionData('initializeModuleAndExtension', [ delegatedManagerAddress ]);
  }
Example #14
Source File: commitments.ts    From hubble-contracts with MIT License 6 votes vote down vote up
constructor(
        public stateRoot: BytesLike,
        public accountRoot: BytesLike,
        public signature: solG1,
        public spokeID: BigNumberish,
        public withdrawRoot: BytesLike,
        public tokenID: BigNumberish,
        public amount: BigNumberish,
        public feeReceiver: BigNumberish,
        public txs: BytesLike
    ) {
        super(stateRoot);
    }
Example #15
Source File: TradeExtensionAPI.ts    From set.js with Apache License 2.0 6 votes vote down vote up
/**
   * Generates `moduleAndExtensionInitialization` bytecode to be passed as an element in the  `initializeBytecode`
   * array for the `initializeAsync` method.
   *
   * @param setTokenAddress              Instance of deployed setToken to initialize the TradeModule for
   *
   * @return                             Initialization bytecode
   */
  public getTradeModuleAndExtensionInitializationBytecode(delegatedManagerAddress: Address): BytesLike {
    this.assert.schema.isValidAddress('delegatedManagerAddress', delegatedManagerAddress);

    const extensionInterface = new EthersUtils.Interface(TradeExtension__factory.abi);
    return extensionInterface.encodeFunctionData('initializeModuleAndExtension', [ delegatedManagerAddress ]);
  }
Example #16
Source File: decimal.ts    From hubble-contracts with MIT License 5 votes vote down vote up
public decompress(input: BytesLike): BigNumber {
        const mantissa = this.mantissaMax.and(input);
        const exponent = this.exponentMask.and(input).shr(this.mantissaBits);

        return mantissa.mul(BigNumber.from(10).pow(exponent));
    }
Example #17
Source File: wallet-connect.wallet-provider.ts    From etherspot-sdk with MIT License 5 votes vote down vote up
async signMessage(message: BytesLike): Promise<string> {
    const response = await this.connector.signPersonalMessage([
      toHex(message), //
      this.address,
    ]);

    return response || null;
  }
Example #18
Source File: commitments.ts    From hubble-contracts with MIT License 5 votes vote down vote up
constructor(public stateRoot: BytesLike) {}
Example #19
Source File: wallet.service.ts    From etherspot-sdk with MIT License 5 votes vote down vote up
async signMessage(message: BytesLike): Promise<string> {
    return this.provider ? this.provider.signMessage(message) : null;
  }
Example #20
Source File: DelegatedManagerFactoryAPI.ts    From set.js with Apache License 2.0 5 votes vote down vote up
/**
   * Wires SetToken, DelegatedManager, global manager extensions, and modules together into a functioning
   * package. `initializeTargets` and `initializeBytecode` params are isomorphic, e.g the arrays must
   * be the same length and the bytecode at `initializeBytecode[i]` will be called on `initializeTargets[i]`;
   *
   * Use the generateBytecode methods provided by this API to prepare parameters for calls to `initialize`
   * as below:
   *
   * ```
   * tradeModuleBytecodeData = api.getTradeModuleInitializationBytecode(setTokenAddress)
   * initializeTargets.push(tradeModuleAddress);
   * initializeBytecode.push(tradeModuleBytecodeData);
   * ```
   *
   * @param setTokenAddress        Address of deployed SetToken to initialize
   * @param ownerFeeSplit          % of fees in precise units (10^16 = 1%) sent to owner, rest to methodologist
   * @param ownerFeeRecipient      Address which receives operator's share of fees when they're distributed
   * @param initializeTargets      Addresses of extensions or modules which should be initialized
   * @param initializeBytecode     Array of encoded calls to a target's initialize function
   * @param callerAddress          Address of caller (optional)
   * @param txOpts                 Overrides for transaction (optional)
   *
   * @return                       Transaction hash of the initialize transaction
   */
  public async initializeAsync(
    setTokenAddress: Address,
    ownerFeeSplit: BigNumberish,
    ownerFeeRecipient: Address,
    initializeTargets: Address[],
    initializeBytecode: BytesLike[],
    callerAddress: Address = undefined,
    txOpts: TransactionOverrides = {}
  ): Promise<ContractTransaction> {
    this.assert.schema.isValidAddress('setTokenAddress', setTokenAddress);
    this.assert.schema.isValidNumber('ownerFeeSplit', ownerFeeSplit);
    this.assert.schema.isValidAddress('ownerFeeRecipient', ownerFeeRecipient);
    this.assert.schema.isValidAddressList('initializeTargets', initializeTargets);
    this.assert.schema.isValidBytesList('initializeBytecode', initializeBytecode);

    this.assert.common.isNotEmptyArray(
      initializeTargets,
      'initializationTargets array must contain at least one element.'
    );

    this.assert.common.isEqualLength(
      initializeTargets,
      initializeBytecode,
      'initializeTargets and initializeBytecode arrays must be equal length.'
    );

    return await this.DelegatedManagerFactoryWrapper.initialize(
      setTokenAddress,
      ownerFeeSplit,
      ownerFeeRecipient,
      initializeTargets,
      initializeBytecode,
      callerAddress,
      txOpts
    );
  }
Example #21
Source File: ens-controller.contract.ts    From etherspot-sdk with MIT License 5 votes vote down vote up
encodeSetPubkey?(node: string, x: BytesLike, y: BytesLike): TransactionRequest;
Example #22
Source File: UpgradeabilityProxy__factory.ts    From commonwealth with GNU General Public License v3.0 5 votes vote down vote up
getDeployTransaction(
    _logic: string,
    _data: BytesLike,
    overrides?: PayableOverrides & { from?: string | Promise<string> }
  ): TransactionRequest {
    return super.getDeployTransaction(_logic, _data, overrides || {});
  }
Example #23
Source File: MerkleRedeem.test.ts    From balancer-v2-monorepo with GNU General Public License v3.0 4 votes vote down vote up
describe('MerkleRedeem', () => {
  let rewardTokens: TokenList, rewardToken: Token, vault: Contract, merkleRedeem: Contract;

  let admin: SignerWithAddress, lp1: SignerWithAddress, lp2: SignerWithAddress, other: SignerWithAddress;
  const rewardTokenInitialBalance = bn(100e18);
  const week1 = bn(1);

  before('setup', async () => {
    [, admin, lp1, lp2, other] = await ethers.getSigners();
  });

  sharedBeforeEach('deploy vault and tokens', async () => {
    const vaultHelper = await Vault.create({ admin });
    vault = vaultHelper.instance;

    rewardTokens = await TokenList.create(['DAI'], { sorted: true });
    rewardToken = rewardTokens.DAI;

    merkleRedeem = await deploy('MerkleRedeem', {
      args: [vault.address, rewardToken.address],
      from: admin,
    });
    await rewardTokens.mint({ to: admin.address, amount: rewardTokenInitialBalance });
    await rewardTokens.approve({ to: merkleRedeem.address, from: [admin] });
  });

  it('stores an allocation', async () => {
    const claimBalance = bn('9876');

    const elements = [encodeElement(lp1.address, claimBalance)];
    const merkleTree = new MerkleTree(elements);
    const root = merkleTree.getHexRoot();

    await merkleRedeem.connect(admin).seedAllocations(week1, root, claimBalance);

    const proof = merkleTree.getHexProof(elements[0]);

    const result = await merkleRedeem.verifyClaim(lp1.address, 1, claimBalance, proof);
    expect(result).to.equal(true);
  });

  it('emits RewardAdded when an allocation is stored', async () => {
    const claimBalance = bn('9876');

    const elements = [encodeElement(lp1.address, claimBalance)];
    const merkleTree = new MerkleTree(elements);
    const root = merkleTree.getHexRoot();

    const receipt = await (await merkleRedeem.connect(admin).seedAllocations(week1, root, claimBalance)).wait();

    expectEvent.inReceipt(receipt, 'RewardAdded', {
      token: rewardToken.address,
      amount: claimBalance,
    });
  });

  it('requisitions tokens when it stores a balance', async () => {
    const claimBalance = bn('9876');

    const elements = [encodeElement(lp1.address, claimBalance)];
    const merkleTree = new MerkleTree(elements);
    const root = merkleTree.getHexRoot();

    await expectBalanceChange(
      () => merkleRedeem.connect(admin).seedAllocations(week1, root, claimBalance),
      rewardTokens,
      [
        { account: admin, changes: { DAI: claimBalance.mul(-1) } },
        { account: merkleRedeem, changes: { DAI: claimBalance } },
      ]
    );
  });

  it('reverts when unauthorized to seed allocation', async () => {
    const claimBalance = bn('9876');

    const elements = [encodeElement(lp1.address, claimBalance)];
    const merkleTree = new MerkleTree(elements);
    const root = merkleTree.getHexRoot();

    await expect(merkleRedeem.connect(other).seedAllocations(week1, root, claimBalance)).to.be.revertedWith(
      'CALLER_IS_NOT_OWNER'
    );
  });

  it('stores multiple allocations', async () => {
    const claimBalance0 = bn('1000');
    const claimBalance1 = bn('2000');

    const elements = [encodeElement(lp1.address, claimBalance0), encodeElement(lp2.address, claimBalance1)];
    const merkleTree = new MerkleTree(elements);
    const root = merkleTree.getHexRoot();

    await merkleRedeem.connect(admin).seedAllocations(1, root, bn('3000'));

    const proof0 = merkleTree.getHexProof(elements[0]);
    let result = await merkleRedeem.verifyClaim(lp1.address, 1, claimBalance0, proof0);
    expect(result).to.equal(true); //"account 0 should have an allocation";

    const proof1 = merkleTree.getHexProof(elements[1]);
    result = await merkleRedeem.verifyClaim(lp2.address, 1, claimBalance1, proof1);
    expect(result).to.equal(true); // "account 1 should have an allocation";
  });

  describe('with an allocation', () => {
    const claimableBalance = bn('1000');
    let elements: string[];
    let merkleTree: MerkleTree;

    sharedBeforeEach(async () => {
      elements = [encodeElement(lp1.address, claimableBalance)];
      merkleTree = new MerkleTree(elements);
      const root = merkleTree.getHexRoot();

      await merkleRedeem.connect(admin).seedAllocations(1, root, claimableBalance);
    });

    it('allows the user to claimWeek', async () => {
      const merkleProof: BytesLike[] = merkleTree.getHexProof(elements[0]);

      await expectBalanceChange(
        () => merkleRedeem.connect(lp1).claimWeek(lp1.address, 1, claimableBalance, merkleProof),
        rewardTokens,
        [{ account: lp1, changes: { DAI: claimableBalance } }]
      );
    });

    it('emits RewardPaid when an allocation is claimed', async () => {
      const merkleProof: BytesLike[] = merkleTree.getHexProof(elements[0]);

      const receipt = await (
        await merkleRedeem.connect(lp1).claimWeek(lp1.address, 1, claimableBalance, merkleProof)
      ).wait();

      expectEvent.inReceipt(receipt, 'RewardPaid', {
        user: lp1.address,
        rewardToken: rewardToken.address,
        amount: claimableBalance,
      });
    });

    it('marks claimed weeks as claimed', async () => {
      const merkleProof: BytesLike[] = merkleTree.getHexProof(elements[0]);
      await merkleRedeem.connect(lp1).claimWeek(lp1.address, 1, claimableBalance, merkleProof);

      const isClaimed = await merkleRedeem.claimed(1, lp1.address);
      expect(isClaimed).to.equal(true); // "claim should be marked as claimed";
    });

    it('reverts when a user attempts to claim for another user', async () => {
      const merkleProof = merkleTree.getHexProof(elements[0]);

      const errorMsg = 'user must claim own balance';
      await expect(
        merkleRedeem.connect(other).claimWeek(lp1.address, 1, claimableBalance, merkleProof)
      ).to.be.revertedWith(errorMsg);
    });

    it('reverts when the user attempts to claim the wrong balance', async () => {
      const incorrectClaimedBalance = bn('666');
      const merkleProof = merkleTree.getHexProof(elements[0]);
      const errorMsg = 'Incorrect merkle proof';
      await expect(
        merkleRedeem.connect(lp1).claimWeek(lp1.address, 1, incorrectClaimedBalance, merkleProof)
      ).to.be.revertedWith(errorMsg);
    });

    it('reverts when the user attempts to claim twice', async () => {
      const merkleProof = merkleTree.getHexProof(elements[0]);

      await merkleRedeem.connect(lp1).claimWeek(lp1.address, 1, claimableBalance, merkleProof);

      const errorMsg = 'cannot claim twice';
      await expect(
        merkleRedeem.connect(lp1).claimWeek(lp1.address, 1, claimableBalance, merkleProof)
      ).to.be.revertedWith(errorMsg);
    });

    it('reverts when an admin attempts to overwrite an allocationn', async () => {
      const elements2 = [encodeElement(lp1.address, claimableBalance), encodeElement(lp2.address, claimableBalance)];
      const merkleTree2 = new MerkleTree(elements2);
      const root2 = merkleTree2.getHexRoot();

      const errorMsg = 'cannot rewrite merkle root';
      expect(merkleRedeem.connect(admin).seedAllocations(1, root2, claimableBalance.mul(2))).to.be.revertedWith(
        errorMsg
      );
    });
  });

  describe('with several allocations', () => {
    const claimBalance1 = bn('1000');
    const claimBalance2 = bn('1234');

    let elements1: string[];
    let merkleTree1: MerkleTree;
    let root1: string;

    let elements2: string[];
    let merkleTree2: MerkleTree;
    let root2: string;

    sharedBeforeEach(async () => {
      elements1 = [encodeElement(lp1.address, claimBalance1)];
      merkleTree1 = new MerkleTree(elements1);
      root1 = merkleTree1.getHexRoot();

      elements2 = [encodeElement(lp1.address, claimBalance2)];
      merkleTree2 = new MerkleTree(elements2);
      root2 = merkleTree2.getHexRoot();

      await merkleRedeem.connect(admin).seedAllocations(week1, root1, claimBalance1);

      await merkleRedeem.connect(admin).seedAllocations(bn(2), root2, claimBalance2);
    });

    it('allows the user to claim multiple weeks at once', async () => {
      const claimedBalance1 = bn('1000');
      const claimedBalance2 = bn('1234');

      const proof1: BytesLike[] = merkleTree1.getHexProof(elements1[0]);
      const proof2: BytesLike[] = merkleTree2.getHexProof(elements2[0]);

      const merkleProofs = [
        { week: week1, balance: claimedBalance1, merkleProof: proof1 },
        { week: bn(2), balance: claimedBalance2, merkleProof: proof2 },
      ];

      await expectBalanceChange(() => merkleRedeem.connect(lp1).claimWeeks(lp1.address, merkleProofs), rewardTokens, [
        { account: lp1, changes: { DAI: bn('2234') } },
      ]);
    });

    it('allows the user to claim multiple weeks at once to internal balance', async () => {
      const claimedBalance1 = bn('1000');
      const claimedBalance2 = bn('1234');

      const proof1: BytesLike[] = merkleTree1.getHexProof(elements1[0]);
      const proof2: BytesLike[] = merkleTree2.getHexProof(elements2[0]);

      const merkleProofs = [
        { week: week1, balance: claimedBalance1, merkleProof: proof1 },
        { week: bn(2), balance: claimedBalance2, merkleProof: proof2 },
      ];

      await expectBalanceChange(
        () => merkleRedeem.connect(lp1).claimWeeksToInternalBalance(lp1.address, merkleProofs),
        rewardTokens,
        [{ account: lp1, changes: { DAI: bn('2234') } }],
        vault
      );
    });

    it('reports weeks as unclaimed', async () => {
      const expectedResult = [false, false];
      const result = await merkleRedeem.claimStatus(lp1.address, 1, 2);
      expect(result).to.eql(expectedResult);
    });

    it('returns an array of merkle roots', async () => {
      const expectedResult = [root1, root2];
      const result = await merkleRedeem.merkleRoots(1, 2);
      expect(result).to.eql(expectedResult); // "claim status should be accurate"
    });

    interface Claim {
      week: BigNumber;
      balance: BigNumber;
      merkleProof: BytesLike[];
    }

    describe('with a callback', () => {
      let callbackContract: Contract;
      let claims: Claim[];

      sharedBeforeEach('set up mock callback', async () => {
        callbackContract = await deploy('MockRewardCallback');

        const proof1: BytesLike[] = merkleTree1.getHexProof(elements1[0]);
        const proof2: BytesLike[] = merkleTree2.getHexProof(elements2[0]);

        claims = [
          { week: bn(1), balance: claimBalance1, merkleProof: proof1 },
          { week: bn(2), balance: claimBalance2, merkleProof: proof2 },
        ];
      });

      it('allows a user to claim the reward to a callback contract', async () => {
        const expectedReward = claimBalance1.add(claimBalance2);
        const calldata = utils.defaultAbiCoder.encode([], []);

        await expectBalanceChange(
          () =>
            merkleRedeem.connect(lp1).claimWeeksWithCallback(lp1.address, callbackContract.address, calldata, claims),
          rewardTokens,
          [{ account: callbackContract.address, changes: { DAI: ['very-near', expectedReward] } }],
          vault
        );
      });

      it('calls the callback on the contract', async () => {
        const calldata = utils.defaultAbiCoder.encode([], []);

        const receipt = await (
          await merkleRedeem
            .connect(lp1)
            .claimWeeksWithCallback(lp1.address, callbackContract.address, calldata, claims)
        ).wait();

        expectEvent.inIndirectReceipt(receipt, callbackContract.interface, 'CallbackReceived', {});
      });
    });

    describe('When a user has claimed one of their allocations', async () => {
      sharedBeforeEach(async () => {
        const claimedBalance1 = bn('1000');
        const proof1 = merkleTree1.getHexProof(elements1[0]);

        const merkleProofs = [{ week: week1, balance: claimedBalance1, merkleProof: proof1 }];

        await merkleRedeem.connect(lp1).claimWeeks(lp1.address, merkleProofs);
      });

      it('reports one of the weeks as claimed', async () => {
        const expectedResult = [true, false];
        const result = await merkleRedeem.claimStatus(lp1.address, 1, 2);
        expect(result).to.eql(expectedResult);
      });
    });
  });
});
Example #24
Source File: TradeExtensionAPI.spec.ts    From set.js with Apache License 2.0 4 votes vote down vote up
describe('TradeExtensionAPI', () => {
  let owner: Address;
  let setToken: Address;
  let tradeExtension: Address;
  let delegatedManager: Address;
  let sendToken: Address;
  let receiveToken: Address;

  let tradeExtensionAPI: TradeExtensionAPI;
  let tradeExtensionWrapper: TradeExtensionWrapper;

  beforeEach(async () => {
    [
      owner,
      setToken,
      delegatedManager,
      tradeExtension,
      sendToken,
      receiveToken,
    ] = await provider.listAccounts();

    tradeExtensionAPI = new TradeExtensionAPI(provider, tradeExtension);
    tradeExtensionWrapper = (TradeExtensionWrapper as any).mock.instances[0];
  });

  afterEach(() => {
    (TradeExtensionWrapper as any).mockClear();
  });

  describe('#tradeWithOperatorAsync', () => {
    let subjectSetToken: Address;
    let subjectExchangeName: string;
    let subjectSendToken: Address;
    let subjectSendQuantity: BigNumber;
    let subjectReceiveToken: Address;
    let subjectMinReceiveQuantity: BigNumber;
    let subjectData: string;
    let subjectCallerAddress: Address;
    let subjectTransactionOptions: any;

    beforeEach(async () => {
      subjectSetToken = setToken;
      subjectExchangeName = 'UniswapV3';
      subjectSendToken = sendToken;
      subjectSendQuantity = ether(1);
      subjectReceiveToken = receiveToken;
      subjectMinReceiveQuantity = ether(.5);
      subjectData = '0x123456789abcdedf';
      subjectCallerAddress = owner;
      subjectTransactionOptions = {};
    });

    async function subject(): Promise<ContractTransaction> {
      return tradeExtensionAPI.tradeWithOperatorAsync(
        subjectSetToken,
        subjectExchangeName,
        subjectSendToken,
        subjectSendQuantity,
        subjectReceiveToken,
        subjectMinReceiveQuantity,
        subjectData,
        subjectCallerAddress,
        subjectTransactionOptions
      );
    }

    it('should call `tradeWithOperator` on the TradeExtensionWrapper', async () => {
      await subject();

      expect(tradeExtensionWrapper.tradeWithOperator).to.have.beenCalledWith(
        subjectSetToken,
        subjectExchangeName,
        subjectSendToken,
        subjectSendQuantity,
        subjectReceiveToken,
        subjectMinReceiveQuantity,
        subjectData,
        subjectCallerAddress,
        subjectTransactionOptions
      );
    });

    describe('when a setToken is not a valid address', () => {
      beforeEach(() => subjectSetToken = '0xinvalid');

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });

    describe('when a exchangeName is not a valid string', () => {
      beforeEach(() => subjectExchangeName = <unknown>5 as string);

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });

    describe('when a sendToken is not a valid address', () => {
      beforeEach(() => subjectSendToken = '0xinvalid');

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });

    describe('when sendQuantity is not a valid number', () => {
      beforeEach(() => subjectSendQuantity = <unknown>NaN as BigNumber);

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });

    describe('when a receiveToken is not a valid address', () => {
      beforeEach(() => subjectReceiveToken = '0xinvalid');

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });

    describe('when minReceiveQuantity is not a valid number', () => {
      beforeEach(() => subjectMinReceiveQuantity = <unknown>NaN as BigNumber);

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });
  });

  describe('#getTradeExtensionInitializationBytecode', () => {
    let subjectDelegatedManager: Address;

    beforeEach(async () => {
      subjectDelegatedManager = delegatedManager;
    });

    async function subject(): Promise<BytesLike> {
      return tradeExtensionAPI.getTradeExtensionInitializationBytecode(
        subjectDelegatedManager
      );
    }

    it('should generate the expected bytecode', async () => {
      const expectedBytecode = '0xde2236bd000000000000000000000000e36ea790bc9d7ab70c55260c66d52b1eca985f84';
      expect(await subject()).eq(expectedBytecode);
    });

    describe('when delegatedManager is not a valid address', () => {
      beforeEach(() => subjectDelegatedManager = '0xinvalid');

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });
  });

  describe('#getTradeModuleAndExtensionInitializationBytecode', () => {
    let subjectDelegatedManager: Address;

    beforeEach(async () => {
      subjectDelegatedManager = delegatedManager;
    });

    async function subject(): Promise<BytesLike> {
      return tradeExtensionAPI.getTradeModuleAndExtensionInitializationBytecode(subjectDelegatedManager);
    }

    it('should generate the expected bytecode', async () => {
      const expectedBytecode = '0x9b468312000000000000000000000000e36ea790bc9d7ab70c55260c66d52b1eca985f84';

      expect(await subject()).eq(expectedBytecode);
    });

    describe('when setToken is not a valid address', () => {
      beforeEach(() => subjectDelegatedManager = '0xinvalid');

      it('should throw with invalid params', async () => {
        await expect(subject()).to.be.rejectedWith('Validation error');
      });
    });
  });
});
Example #25
Source File: executionManager.ts    From nova with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * Checks an exec tx emitted events with reasonable values.
 * Will revert if execCompleted reverts.
 */
export async function executeRequest(
  L1_NovaExecutionManager: L1NovaExecutionManager,

  config: {
    nonce?: number;
    strategy: string;
    l1Calldata?: BytesLike;
    gasLimit?: number;
    l2Recipient?: string;
    deadline?: number;
    shouldSoftRevert?: boolean;
    relayer: string;
    gasPrice?: number;
    expectedGasOverestimateAmount?: number;
  }
) {
  // Init default values if not provided.
  config.nonce = config.nonce ?? globalNonce++;
  config.l1Calldata = config.l1Calldata ?? "0x00";
  config.gasLimit = config.gasLimit ?? 300_000;
  config.l2Recipient = config.l2Recipient ?? config.relayer;
  config.deadline = config.deadline ?? 9999999999999;
  config.shouldSoftRevert = config.shouldSoftRevert ?? false;
  config.expectedGasOverestimateAmount = config.expectedGasOverestimateAmount ?? 0;

  const {
    nonce,
    strategy,
    l1Calldata,
    gasLimit,
    l2Recipient,
    deadline,
    shouldSoftRevert,
    expectedGasOverestimateAmount,
    relayer,
    gasPrice,
  } = config;

  const tx = L1_NovaExecutionManager.exec(
    nonce,
    strategy,
    l1Calldata,
    gasLimit,
    l2Recipient,
    deadline,
    { type: 0, gasPrice }
  );
  const awaitedTx = await tx;

  // Get events and gas used from the tx.
  const { gasUsed, events } = await awaitedTx.wait();
  const execEvent = events[events.length - 1];

  // Compute the execHash for the execution.
  const execHash = computeExecHash({
    nonce,
    strategy,
    calldata: l1Calldata.toString(),
    gasPrice: awaitedTx.gasPrice.toNumber(),
    gasLimit,
  });

  // Did it properly compute the request's execHash.
  execEvent.args.execHash.should.equal(execHash);

  // Was the relayer emitted as expected.
  execEvent.args.relayer.should.equal(relayer);

  // Did the request soft revert like intended (or not).
  execEvent.args.reverted.should.equal(shouldSoftRevert);

  // Only check gas estimates if we're not in coverage mode, as gas estimates are messed up in coverage mode.
  if (!process.env.HARDHAT_COVERAGE_MODE_ENABLED) {
    // The gasUsed estimate in the event should always be more than the actual gas used, but should never be more than 16,000 gas above.
    const overestimateAmount = execEvent.args.gasUsed.toNumber() - gasUsed.toNumber();
    overestimateAmount.should.be.within(0, 1000 + expectedGasOverestimateAmount);
  }

  return { tx, execHash, gasUsed, execEvent, ...config };
}