diff --git a/contracts/mainnet/common/interfaces.sol b/contracts/mainnet/common/interfaces.sol index 9b872418..4fa3bec9 100644 --- a/contracts/mainnet/common/interfaces.sol +++ b/contracts/mainnet/common/interfaces.sol @@ -11,6 +11,7 @@ interface TokenInterface { function balanceOf(address) external view returns (uint); function decimals() external view returns (uint); function totalSupply() external view returns (uint); + function allowance(address owner, address spender) external view returns (uint256); } interface MemoryInterface { diff --git a/contracts/mainnet/connectors/compound-iii/helpers.sol b/contracts/mainnet/connectors/compound-iii/helpers.sol index b416e40d..3ee3ac73 100644 --- a/contracts/mainnet/connectors/compound-iii/helpers.sol +++ b/contracts/mainnet/connectors/compound-iii/helpers.sol @@ -66,7 +66,7 @@ abstract contract Helpers is DSMath, Basic { params.market != address(0) && params.token != address(0), "invalid market/token address" ); - bool isEth = params.token == ethAddr; + bool isEth = params.token == ethAddr || params.token == wethAddr; address token_ = isEth ? wethAddr : params.token; TokenInterface tokenContract = TokenInterface(token_); @@ -85,7 +85,9 @@ abstract contract Helpers is DSMath, Basic { params.from = params.from == address(0) ? address(this) : params.from; - uint256 balance = CometInterface(params.market).balanceOf(params.from); + uint256 balance = TokenInterface(params.market).balanceOf( + params.from + ); if (balance > 0) { require( amt_ <= balance, @@ -97,7 +99,9 @@ abstract contract Helpers is DSMath, Basic { params.from = params.from == address(0) ? address(this) : params.from; - uint256 balance = CometInterface(params.market).balanceOf(params.from); + uint256 balance = TokenInterface(params.market).balanceOf( + params.from + ); require(balance == 0, "borrow-disabled-when-supplied-base"); } @@ -126,7 +130,7 @@ abstract contract Helpers is DSMath, Basic { ) internal returns (uint256 balance) { if (asset == getBaseToken(market)) { //balance in base - balance = CometInterface(market).balanceOf(account); + balance = TokenInterface(market).balanceOf(account); } else { //balance in asset denomination balance = uint256( @@ -140,26 +144,44 @@ abstract contract Helpers is DSMath, Basic { address token, address src, uint256 amt, - bool isEth + bool isEth, + bool isRepay ) internal returns (uint256) { if (isEth) { if (amt == uint256(-1)) { - uint256 allowance_ = CometInterface(market).allowance( + uint256 allowance_ = TokenInterface(token).allowance( src, market ); - amt = src.balance < allowance_ ? src.balance : allowance_; + uint256 bal_; + if (isRepay) { + bal_ = CometInterface(market).borrowBalanceOf(src); + } else { + bal_ = src.balance; + } + amt = bal_ < allowance_ ? bal_ : allowance_; } convertEthToWeth(isEth, TokenInterface(token), amt); } else { if (amt == uint256(-1)) { - uint256 allowance_ = CometInterface(market).allowance( + uint256 allowance_ = TokenInterface(token).allowance( src, market ); - uint256 bal_ = (token == getBaseToken(market)) - ? TokenInterface(market).balanceOf(src) - : CometInterface(market).userCollateral(src, token).balance; + uint256 bal_; + if (isRepay) { + bal_ = (token == getBaseToken(market)) + ? CometInterface(market).borrowBalanceOf(src) + : CometInterface(market) + .userCollateral(src, token) + .balance; + } else { + bal_ = (token == getBaseToken(market)) + ? TokenInterface(market).balanceOf(src) + : CometInterface(market) + .userCollateral(src, token) + .balance; + } amt = bal_ < allowance_ ? bal_ : allowance_; } diff --git a/contracts/mainnet/connectors/compound-iii/main.sol b/contracts/mainnet/connectors/compound-iii/main.sol index 5eb3c9f4..07265559 100644 --- a/contracts/mainnet/connectors/compound-iii/main.sol +++ b/contracts/mainnet/connectors/compound-iii/main.sol @@ -169,7 +169,7 @@ abstract contract CompoundV3Resolver is Events, Helpers { ); } - amt_ = setAmt(market, token_, from, amt_, isEth); + amt_ = setAmt(market, token_, from, amt_, isEth, false); CometInterface(market).supplyFrom(from, to, token_, amt_); setUint(setId, amt_); @@ -345,9 +345,8 @@ abstract contract CompoundV3Resolver is Events, Helpers { require(market != address(0), "invalid market address"); - address token = getBaseToken(market); - bool isEth = token == ethAddr; - address token_ = isEth ? wethAddr : token; + address token_ = getBaseToken(market); + bool isEth = token_ == wethAddr; TokenInterface tokenContract = TokenInterface(token_); @@ -477,9 +476,8 @@ abstract contract CompoundV3Resolver is Events, Helpers { uint256 amt_ = getUint(getId, amt); require(market != address(0), "invalid market address"); - address token = getBaseToken(market); - bool isEth = token == ethAddr; - address token_ = isEth ? wethAddr : token; + address token_ = getBaseToken(market); + bool isEth = token == wethAddr; TokenInterface tokenContract = TokenInterface(token_); amt_ = amt_ == uint256(-1) @@ -493,9 +491,6 @@ abstract contract CompoundV3Resolver is Events, Helpers { require(amt_ <= borrowBal, "repay-amt-greater-than-debt"); } - if (isEth) { - convertEthToWeth(isEth, tokenContract, amt_); - } approve(tokenContract, market, amt_); CometInterface(market).supply(token_, amt_); @@ -529,9 +524,8 @@ abstract contract CompoundV3Resolver is Events, Helpers { uint256 amt_ = getUint(getId, amt); require(market != address(0), "invalid market address"); - address token = getBaseToken(market); - bool isEth = token == ethAddr; - address token_ = isEth ? wethAddr : token; + address token_ = getBaseToken(market); + bool isEth = token == wethAddr; TokenInterface tokenContract = TokenInterface(token_); amt_ = amt_ == uint256(-1) @@ -542,11 +536,6 @@ abstract contract CompoundV3Resolver is Events, Helpers { if (borrowBal > 0) { require(amt_ <= borrowBal, "repay-amt-greater-than-debt"); } - - if (isEth) { - convertEthToWeth(isEth, tokenContract, amt_); - } - approve(tokenContract, market, amt_); CometInterface(market).supplyTo(to, token_, amt_); @@ -582,22 +571,17 @@ abstract contract CompoundV3Resolver is Events, Helpers { uint256 amt_ = getUint(getId, amt); require(market != address(0), "invalid market address"); - address token = getBaseToken(market); - bool isEth = token == ethAddr; - address token_ = isEth ? wethAddr : token; + address token_ = getBaseToken(market); + bool isEth = token == wethAddr; TokenInterface tokenContract = TokenInterface(token_); - amt_ = setAmt(market, token_, from, amt_, isEth); + amt_ = setAmt(market, token_, from, amt_, isEth, true); uint256 borrowBal = CometInterface(market).borrowBalanceOf(to); if (borrowBal > 0) { require(amt_ <= borrowBal, "repay-amt-greater-than-debt"); } - if (isEth) { - convertEthToWeth(isEth, tokenContract, amt_); - } - approve(tokenContract, market, amt_); CometInterface(market).supplyFrom(from, to, token_, amt_); @@ -751,7 +735,7 @@ abstract contract CompoundV3Resolver is Events, Helpers { address token_ = isEth ? wethAddr : token; TokenInterface tokenContract = TokenInterface(token_); - amt_ = setAmt(market, token_, src, amt_, isEth); + amt_ = setAmt(market, token_, src, amt_, isEth, false); _transfer(market, token_, src, dest, amt_); diff --git a/test/mainnet/compound/compound.iii.test.ts b/test/mainnet/compound/compound.iii.test.ts index 7a21a0f3..40d05ef5 100644 --- a/test/mainnet/compound/compound.iii.test.ts +++ b/test/mainnet/compound/compound.iii.test.ts @@ -23,7 +23,10 @@ describe("Compound III", function () { const base = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; const account = "0x72a53cdbbcc1b9efa39c834a540550e23463aacb"; - const ABI = ["function balanceOf(address account) public view returns (uint256)"]; + const ABI = [ + "function balanceOf(address account) public view returns (uint256)", + "function approve(address spender, uint256 amount) external returns(bool)" + ]; const wethContract = new ethers.Contract(tokens.weth.address, ABI); const baseContract = new ethers.Contract(base, ABI); const linkContract = new ethers.Contract(tokens.link.address, ABI); @@ -312,21 +315,12 @@ describe("Compound III", function () { } ]; - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); + const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); const receipt = await tx.wait(); - expect(await comet.connect(signer).balanceOf(dsaWallet0.address)).to.be.equal(ethers.utils.parseUnits("0", 6)); + expect(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).to.be.equal(ethers.utils.parseUnits("0", 6)); }); it("Should borrow on behalf of from Compound", async function () { - const spells1 = [ - { - connector: connectorName, - method: "deposit", - args: [market, tokens.eth.address, ethers.utils.parseEther("6"), 0, 0] - } - ]; - - const tx1 = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address); const amount = ethers.utils.parseUnits("100", 6); const spells = [ { @@ -342,7 +336,7 @@ describe("Compound III", function () { ethers.utils.parseUnits("100", 6) ); //dsawallet0 --> collateral 6eth, balance 5eth, 100usdc - //dsaWallet1 --> balance 3eth coll: 0eth + //dsaWallet1 --> balance 9eth coll: 0eth }); it("Should payback on behalf of from Compound", async function () {