Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting AugustusSwapper's utility functions for singleSwaps #240

Merged
merged 12 commits into from
Apr 28, 2021

Conversation

olivdb
Copy link
Contributor

@olivdb olivdb commented Apr 27, 2021

Supporting AugustusSwapper's utility functions for singleSwaps


function isValid(address /*_wallet*/, address _spender, address _to, bytes calldata _data) external view override returns (bool valid) {
// disable ETH transfer
if (_data.length < 4) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wallets should be able to deposit ETH via the fallback function so we should accept calls where _data.length == 0.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

@@ -269,14 +280,49 @@ contract ParaswapFilter is BaseFilter {
uint256 exchangeDataOffset = 36 + abi.decode(_data[196:228], (uint256));
address[] memory spenders = new address[](_callees.length);
bytes[] memory allData = new bytes[](_callees.length);
for(uint256 i = 0; i < _callees.length; i++) {
uint256 i;
while(i < _callees.length) {
Copy link
Member

@juniset juniset Apr 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this doesn't work as you are looping over callees.length but you are reducing the length if the callee is augustus so you might never reach the last callee. Also you are not incrementing i when you reduce the size of callees so you will check the same callee twice. Maybe I'm wrong but it's just a sign that this logic is too complicated.

A simpler version of the same logic that I find simpler to read is

function hasAuthorisedCallees(
        address _augustus,
        address[] memory _callees,
        uint256[] memory _startIndexes,
        bytes calldata _data
    )
        internal
        view
        returns (bool)
    {
        // _data = {sig:4}{six params:192}{exchangeDataOffset:32}{...}
        // we add 4+32=36 to the offset to skip the method sig and the size of the exchangeData array
        uint256 exchangeDataOffset = 36 + abi.decode(_data[196:228], (uint256)); 
        address[] memory to = new address[](_callees.length);
        address[] memory spenders = new address[](_callees.length);
        bytes[] memory allData = new bytes[](_callees.length);
        uint256 i;
        while(i < _callees.length) {
            bytes calldata slicedExchangeData = _data[exchangeDataOffset+_startIndexes[i] : exchangeDataOffset+_startIndexes[i+1]];
            if (_callees[i] == _augustus) {
                if (slicedExchangeData.length >= 4 && getMethod(slicedExchangeData) == WITHDRAW_ALL_WETH) {
                    uint newLength = _callees.length - 1;
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        mstore(to, newLength)
                        mstore(spenders, newLength)
                        mstore(allData, newLength)
                    }
                } else {
                    return false;
                }
            } else {
                to[i] = _callees[i];
                allData[i] = slicedExchangeData;
                spenders[i] = Utils.recoverSpender(_callees[i], slicedExchangeData);
            }
            i++;
        }
        return authoriser.areAuthorised(_augustus, spenders, to, allData);
    }

If you agree then we no longer need the CalleeInfo struct and the decodeCalleeData method as we are not hitting a stack too deep error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that using a temporary array for callees is much cleaner

@@ -97,6 +97,8 @@ contract ParaswapFilter is BaseFilter {
bytes4 constant internal MEGASWAP = bytes4(keccak256(
"megaSwap((address,uint256,uint256,uint256,address,string,bool,(uint256,(address,uint256,(address,address,uint256,bytes,uint256)[])[])[]))"
));
bytes4 constant internal APPROVE = bytes4(keccak256("approve(address,address,uint256)"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer needed.

@@ -137,6 +138,15 @@ contract ParaswapFilter is BaseFilter {
bytes32 public immutable uniForkInitCode2; // linkswap
bytes32 public immutable uniForkInitCode3; // defiswap


// Stack Extension for hasAuthorisedCallees()
struct CalleeInfo {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sholul be removed.

@olivdb olivdb changed the base branch from develop to fix/update_filters April 28, 2021 10:34
@juniset juniset merged commit 4712131 into fix/update_filters Apr 28, 2021
@Muzcool
Copy link

Muzcool commented Oct 5, 2021

👌

1 similar comment
@Muzcool
Copy link

Muzcool commented Oct 5, 2021

👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants