Fujicracy / fuji-v2

Cross-chain money market aggregator
https://fuji-v2-frontend.vercel.app
15 stars 10 forks source link

Make ConnextRouter permisionless #220

Closed 0xdcota closed 1 year ago

0xdcota commented 1 year ago

Latest implementation of the BaseRouter and the way Connext pushes funds to the router in the xReceive call, made us make the bridge route permissioned. This means that the connext address calling the router is whitelisted.

Refer to discussion here.

In a brainstorm session, we introduced the idea of using a Holder contract, to make a pattern in where failed connext calls do not leave assets in the router.

unction xReceive(
    bytes32 transferId,
    uint256 amount,
    address asset,
    address, /* originSender */
    uint32 originDomain,
    bytes memory callData
  )
    external
    returns (bytes memory)
  {
    (Action[] memory actions, bytes[] memory args) = abi.decode(callData, (Action[], bytes[]));

    // Block callers except allowed cross callers. <---- this permission should be removed. 
    // if (!_isAllowedCaller[msg.sender]) {
    //  revert ConnextRouter__xReceive_notAllowedCaller();
    //}

    // Ensure that at this entry point expected `asset` `amount` is received.
    if (IERC20(asset).balanceOf(address(this)) < amount) {
      revert ConnextRouter__xReceive_notReceivedAssetBalance();
    } else {
      _tokenList.push(asset);
      BalanceChecker memory checkedToken =
        BalanceChecker(asset, IERC20(asset).balanceOf(address(this)) - amount);
      _tokensToCheck.push(checkedToken);
    }

    holder.receiveAndCheck(); // <-- the holder contract performs logic to either keep the funds or be ready to be pulled back.

    try this.xBundle(actions, args) {
      emit XReceived(transferId, originDomain, true, asset, amount, callData);
    } catch {
      // Else:
      // ensure clear storage for token balance checks
      delete _tokenList;
      delete _tokensToCheck;
      // keep funds in router and let them be handled by admin
      emit XReceived(transferId, originDomain, false, asset, amount, callData);
     // if fails holder contract must do something.
     holder.doSomething();
    }

    return "";
  }
brozorec commented 1 year ago

We can also try to refactor routers to avoid code duplication (like decoding params twice).