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

Uniswap ABIFunction Call getPool #369

Open
wilks7 opened this issue Apr 16, 2024 · 3 comments
Open

Uniswap ABIFunction Call getPool #369

wilks7 opened this issue Apr 16, 2024 · 3 comments

Comments

@wilks7
Copy link

wilks7 commented Apr 16, 2024

I have having an issue with my Uniswap ABIFunction, the function is defined on the Uniswap V3 Router 0x1F98431c8aD98523631AE4a59f267346ea31F984
getPool(address,address,uint24)

fails with
executionError(Code: -32000 Message: execution reverted)

I assume passing BigUInt is sufficient for the uint24 getPool requires

public protocol UniswapProtocol {
    init(client: EthereumRPCProtocol)
    func getPool(
        contract: EthereumAddress,
        tokenIn: EthereumAddress,
        tokenOut: EthereumAddress,
        fee: BigUInt
    ) async throws -> EthereumAddress
}

public class Uniswap: UniswapProtocol {
    public let client: EthereumRPCProtocol
    
    public required init(client: EthereumRPCProtocol) {
        self.client = client
    }
    
    public static let v3_router = EthereumAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984")
    
    public func getPool(
        contract: EthereumAddress = v3_router,
        tokenIn: EthereumAddress,
        tokenOut: EthereumAddress,
        fee: BigUInt = 3000
    ) async throws -> EthereumAddress {
        let function = UniswapFunctions.getPool(contract: contract, tokenIn: tokenIn, tokenOut: tokenOut, fee: fee)
        let response = try await function.call(withClient: client, responseType: UniswapResponses.poolResponse.self)
        
        return response.value
    }
    
}

public enum UniswapFunctions {

    struct getPool: ABIFunction {
        static let name = "getPool"
        
        let contract: EthereumAddress
        let tokenIn: EthereumAddress
        let tokenOut: EthereumAddress
        let fee: BigUInt
        
        public var gasPrice: BigUInt? = nil
        public var gasLimit: BigUInt? = nil
        public var from: web3.EthereumAddress? = nil
        
        init(contract: EthereumAddress, tokenIn: EthereumAddress, tokenOut: EthereumAddress, fee: BigUInt) {
            self.contract = contract
            self.tokenIn = tokenIn
            self.tokenOut = tokenOut
            self.fee = fee
        }
        
        public func encode(to encoder: ABIFunctionEncoder) throws {
            try encoder.encode(tokenIn)
            try encoder.encode(tokenOut)
            try encoder.encode(fee)
        }
    }
}

public enum UniswapResponses {
    public struct poolResponse: ABIResponse, MulticallDecodableResponse {
        
        public static var types: [ABIType.Type] = [EthereumAddress.self]
        public let value: EthereumAddress

        public init?(values: [ABIDecoder.DecodedValue]) throws {
            self.value = try values[0].decoded()
        }
    }
}
func testGetPool() async {
    let rpc =  INFURA_RPC
    let node = EthereumHttpClient(url: rpc, network: .mainnet)
    
    let weth = EthereumAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
    let usdc = EthereumAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
    
    let expectedPool = EthereumAddress("0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8")
    
    let uniswap = Uniswap(client: node)

    do {
        let pool = try await uniswap.getPool(
            tokenIn: weth,
            tokenOut: usdc
        )
        XCTAssertEqual(expectedPool, pool)
    } catch {
        XCTFail("Expected Client to return a WETH - USDC pool \n\(error)")
    }
}
@DarthMike
Copy link
Member

Hi @wilks7 I can't get any reading from that contract from etherscan
It returns 0x00
Screenshot 2024-04-17 at 17 20 07

@wilks7
Copy link
Author

wilks7 commented Apr 17, 2024

it seems there is a typo in your query, the uint24 input should be 3000 not 300, it is the percent fee of a Uniswap pool, if there is no pool at the given percent it returns empty address

either way shouldn't the function still return an empty EthereumAddress instead of failing?

@DarthMike
Copy link
Member

If the call returns executionError(Code: -32000 Message: execution reverted) the result is correct. It fails executing so defaulting to a specific value is not a good behaviour.

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

No branches or pull requests

2 participants