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

feat: create tsx for cow zap transaction #734

Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions packages/contracts/src/dollar/cow-minter/Minter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
import {IUbiquityPool} from "../interfaces/IUbiquityPool.sol";

contract Minter {
address public immutable ubiquityPool;

constructor(address ubiquityPool_) {
ubiquityPool = ubiquityPool_;
}

function getAccountAddress(address user) external view returns (address) {
return _getAccountAddress(user);
}

function getAccountBalance(
address user,
IERC20 token
) public view returns (uint256) {
return token.balanceOf(_getAccountAddress(user));
}

function ensureAccount(address user) public returns (MintAccount) {
address accountAddress = _getAccountAddress(user);
uint256 codeSize;
assembly {
codeSize := extcodesize(accountAddress)
}

if (codeSize > 0) {
return MintAccount(accountAddress);
} else {
MintAccount newAccount = new MintAccount{salt: bytes32(0)}(
user,
ubiquityPool
);
require(
accountAddress == address(newAccount),
"account does not expected deployment address"
);

return newAccount;
}
}

function mint(
address user,
address token,
uint256 amountIn,
uint256 dollarMin
) public {
ensureAccount(user).mintDollar(token, amountIn, dollarMin);
}

function mintAll(address user, address token, uint256 dollarMin) external {
mint(user, token, getAccountBalance(user, IERC20(token)), dollarMin);
}

function withdraw(address user, address token, uint256 amount) public {
ensureAccount(user).withdraw(token, amount);
}

function withdrawAll(address user, address token) external {
withdraw(user, token, getAccountBalance(user, IERC20(token)));
}

function _getAccountAddress(address user) internal view returns (address) {
return
address(
uint160(
uint256(
keccak256(
abi.encodePacked(
bytes1(0xff),
address(this),
bytes32(0),
keccak256(
abi.encodePacked(
type(MintAccount).creationCode,
abi.encode(user, ubiquityPool)
)
)
)
)
)
)
);
}
}

contract MintAccount {
address public immutable user;
address public immutable ubiquityPool;

constructor(address user_, address ubiquityPool_) {
user = user_;
ubiquityPool = ubiquityPool_;
}

function mintDollar(
address token,
uint256 amountIn,
uint256 amountOutMin
) external {
IERC20(token).approve(ubiquityPool, amountIn);
IUbiquityPool(ubiquityPool).mintDollar(
user,
token,
amountIn,
amountOutMin
);
}

function withdraw(address token, uint256 amount) external returns (bool) {
return IERC20(token).transfer(user, amount);
}
}
2 changes: 2 additions & 0 deletions packages/contracts/src/dollar/facets/UbiquityPoolFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ contract UbiquityPoolFacet is Modifiers, IUbiquityPool {
/// @param collateralAmount amount of collateral tokens being deposited
/// @param dollarOutMin minimum amount of UbiquityDollarToken that'll be minted, used to set acceptable slippage
function mintDollar(
address user,
address collateralAddress,
uint256 collateralAmount,
uint256 dollarOutMin
) external {
LibUbiquityPool.mintDollar(
user,
collateralAddress,
collateralAmount,
dollarOutMin
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/dollar/interfaces/IUbiquityPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {IMetaPool} from "./IMetaPool.sol";

interface IUbiquityPool {
function mintDollar(
address user,
address collateralAddress,
uint256 collateralAmount,
uint256 dollarOutMin
Expand Down
9 changes: 6 additions & 3 deletions packages/contracts/src/dollar/libraries/LibUbiquityPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ library LibUbiquityPool {
using SafeERC20 for IERC20;

bytes32 constant UBIQUITY_POOL_STORAGE_POSITION =
bytes32(uint256(keccak256("ubiquity.contracts.ubiquity.pool.storage")) - 1);
bytes32(
uint256(keccak256("ubiquity.contracts.ubiquity.pool.storage")) - 1
);

function ubiquityPoolStorage()
internal
Expand Down Expand Up @@ -74,6 +76,7 @@ library LibUbiquityPool {
/// User Functions ///

function mintDollar(
address user,
address collateralAddress,
uint256 collateralAmount,
uint256 dollarOutMin
Expand Down Expand Up @@ -103,7 +106,7 @@ library LibUbiquityPool {
dollarAmountD18 = dollarAmountD18.sub(poolStorage.mintingFee);
require(dollarOutMin <= dollarAmountD18, "Slippage limit reached");
IERC20(collateralAddress).safeTransferFrom(
msg.sender,
user,
address(this),
collateralAmount
);
Expand All @@ -115,7 +118,7 @@ library LibUbiquityPool {
IERC20Ubiquity ubiquityDollarToken = IERC20Ubiquity(
LibAppStorage.appStorage().dollarTokenAddress
);
ubiquityDollarToken.mint(msg.sender, dollarAmountD18);
ubiquityDollarToken.mint(user, dollarAmountD18);
}

function redeemDollar(
Expand Down
29 changes: 25 additions & 4 deletions packages/contracts/test/diamond/facets/UbiquityPoolFacet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ contract UbiquityPoolFacetTest is DiamondSetup {
collateral.approve(address(IUbiquityPoolFacet), type(uint256).max);
vm.expectRevert("Slippage limit reached");
IUbiquityPoolFacet.mintDollar(
fourthAccount,
address(collateral),
10 ether,
10000 ether
Expand All @@ -228,7 +229,12 @@ contract UbiquityPoolFacetTest is DiamondSetup {
collateral.approve(address(IUbiquityPoolFacet), type(uint256).max);

uint256 balanceBefore = IDollar.balanceOf(fourthAccount);
IUbiquityPoolFacet.mintDollar(address(collateral), 1 ether, 0 ether);
IUbiquityPoolFacet.mintDollar(
fourthAccount,
address(collateral),
1 ether,
0 ether
);
assertGt(IDollar.balanceOf(fourthAccount), balanceBefore);
vm.stopPrank();
}
Expand All @@ -245,7 +251,12 @@ contract UbiquityPoolFacetTest is DiamondSetup {
collateral.approve(address(IUbiquityPoolFacet), type(uint256).max);

uint256 balanceBefore = IDollar.balanceOf(fourthAccount);
IUbiquityPoolFacet.mintDollar(address(collateral), 1 ether, 0 ether);
IUbiquityPoolFacet.mintDollar(
fourthAccount,
address(collateral),
1 ether,
0 ether
);
assertGt(IDollar.balanceOf(fourthAccount), balanceBefore);
vm.stopPrank();

Expand All @@ -270,7 +281,12 @@ contract UbiquityPoolFacetTest is DiamondSetup {
vm.startPrank(fourthAccount);
collateral.approve(address(IUbiquityPoolFacet), type(uint256).max);

IUbiquityPoolFacet.mintDollar(address(collateral), 10 ether, 0 ether);
IUbiquityPoolFacet.mintDollar(
fourthAccount,
address(collateral),
10 ether,
0 ether
);
uint256 balanceBefore = IDollar.balanceOf(fourthAccount);
vm.stopPrank();
MockMetaPool mock = MockMetaPool(IManager.stableSwapMetaPoolAddress());
Expand Down Expand Up @@ -309,7 +325,12 @@ contract UbiquityPoolFacetTest is DiamondSetup {
vm.startPrank(fourthAccount);
collateral.approve(address(IUbiquityPoolFacet), type(uint256).max);

IUbiquityPoolFacet.mintDollar(address(collateral), 10 ether, 0 ether);
IUbiquityPoolFacet.mintDollar(
fourthAccount,
address(collateral),
10 ether,
0 ether
);
uint256 balanceBefore = IDollar.balanceOf(fourthAccount);
uint256 balanceCollateralBefore = collateral.balanceOf(fourthAccount);
vm.stopPrank();
Expand Down
Loading