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

adding value in swap call #13459

Merged
merged 10 commits into from Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions packages/contracts/src/abis/utils/UnlockSwapPurchaser.json

Large diffs are not rendered by default.

47 changes: 28 additions & 19 deletions packages/contracts/src/contracts/utils/UnlockSwapPurchaser.sol
@@ -1,4 +1,4 @@
// Sources flattened with hardhat v2.18.3 https://hardhat.org
// Sources flattened with hardhat v2.20.1 https://hardhat.org

// SPDX-License-Identifier: GPL-2.0-or-later AND MIT

Expand Down Expand Up @@ -749,17 +749,24 @@ interface IPublicLock {
* - `from`, `to` cannot be zero.
* - `tokenId` must be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this
* NFT by either {approve} or {setApprovalForAll}.
* NFT by either `approve` or `setApprovalForAll`.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;

function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;

/**
* an ERC721-like function to transfer a token from one account to another.
* @param from the owner of token to transfer
* @param to the address that will receive the token
* @param tokenId the id of the token
* @dev Requirements: if the caller is not `from`, it must be approved to move this token by
* either {approve} or {setApprovalForAll}.
* either `approve` or `setApprovalForAll`.
* The key manager will be reset to address zero after the transfer
*/
function transferFrom(address from, address to, uint256 tokenId) external;
Expand Down Expand Up @@ -816,13 +823,6 @@ interface IPublicLock {
address _operator
) external view returns (bool);

function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;

/**
* Returns the total number of keys, including non-valid ones
* @return _totalKeysCreated the total number of keys, valid or not
Expand Down Expand Up @@ -1332,6 +1332,17 @@ contract UnlockSwapPurchaser {
: IMintableERC20(token).balanceOf(address(this));
}

/**
* Check if lock exists
* @param lock address of the lock
*/
function lockExists(address lock) internal view returns (bool lockExists) {
(lockExists, , ) = IUnlock(unlockAddress).locks(lock);
if (!lockExists) {
revert LockDoesntExist(lock);
}
}

/**
* Swap tokens and call a function a lock contract.
*
Expand All @@ -1340,6 +1351,7 @@ contract UnlockSwapPurchaser {
*
* @param lock the address of the lock
* @param srcToken the address of the token sent by the user (ERC20 or address(0) for native)
* @param keyPrice the expected price of the token (calculated from the lock)
* @param amountInMax the maximum amount the user want to spend in the swap
* @param uniswapRouter the address of the uniswap router
* @param swapCalldata the Uniswap quote calldata returned by the SDK, to be sent to the router contract
Expand All @@ -1353,18 +1365,15 @@ contract UnlockSwapPurchaser {
function swapAndCall(
address lock,
address srcToken,
uint keyPrice,
uint amountInMax,
address uniswapRouter,
bytes memory swapCalldata,
bytes memory callData
) public payable returns (bytes memory) {
// check if lock exists
(bool lockExists, , ) = IUnlock(unlockAddress).locks(lock);
if (!lockExists) {
revert LockDoesntExist(lock);
}
// make sure the lock is registered in Unlock
lockExists(lock);

// make sure
if (uniswapRouters[uniswapRouter] != true) {
revert UnautorizedRouter(uniswapRouter);
}
Expand Down Expand Up @@ -1428,19 +1437,19 @@ contract UnlockSwapPurchaser {
destToken == address(0)
? getBalance(destToken) - msg.value
: getBalance(destToken)
) < balanceTokenDestBefore + IPublicLock(lock).keyPrice()
) < balanceTokenDestBefore + keyPrice
) {
revert InsufficientBalance();
}

// approve ERC20 to call the lock
if (destToken != address(0)) {
IMintableERC20(destToken).approve(lock, IPublicLock(lock).keyPrice());
IMintableERC20(destToken).approve(lock, keyPrice);
}

// call the lock
(bool lockCallSuccess, bytes memory returnData) = lock.call{
value: destToken == address(0) ? IPublicLock(lock).keyPrice() : 0
value: destToken == address(0) ? keyPrice : 0
}(callData);

if (lockCallSuccess == false) {
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/arbitrum.ts
Expand Up @@ -80,7 +80,7 @@ export const arbitrum: NetworkConfig = {
networkName: 'arbitrum-one',
studioName: 'unlock-protocol-arbitrum',
},
swapPurchaser: '0x0C33884Ab3eE799E7628FA3fCF20B81997745a72',
swapPurchaser: '0xE1a7Ec44fB4c5c88ebB3744A9Ba2A3cCA879A47d',
tokens: [
{
address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/avalanche.ts
Expand Up @@ -65,7 +65,7 @@ export const avalanche: NetworkConfig = {
'https://api.studio.thegraph.com/query/65299/unlock-protocol-avalanche/version/latest',
studioName: 'unlock-protocol-avalanche',
},
swapPurchaser: '0x5c67AD0CAfe61aF3706347aBc695D7ACcb38EFb3',
swapPurchaser: '0xc9F29DdBD4D828cFb2EB491E9d48013a9c0E3C89',
tokens: [
{
address: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/base.ts
Expand Up @@ -79,7 +79,7 @@ export const base: NetworkConfig = {
networkName: 'base',
studioName: 'unlock-protocol-base',
},
swapPurchaser: '0x70B3c9Dd9788570FAAb24B92c3a57d99f8186Cc7',
swapPurchaser: '0x36b34e10295cCE69B652eEB5a8046041074515Da',
tokens: [
{
address: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/bsc.ts
Expand Up @@ -91,7 +91,7 @@ export const bsc: NetworkConfig = {
studioName: 'unlock-protocol-bsc',
},

swapPurchaser: '0xc9F29DdBD4D828cFb2EB491E9d48013a9c0E3C89',
swapPurchaser: '0xe49f5FD63cD7ec130B07dad30f068CC08F201e1e',

tokens: [
{
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/celo.ts
Expand Up @@ -59,7 +59,7 @@ export const celo: NetworkConfig = {
'https://api.studio.thegraph.com/query/65299/unlock-protocol-celo/version/latest',
studioName: 'unlock-protocol-celo',
},
swapPurchaser: '0x42F5c7839Bf00FAea6ca09517E96E82e7364384D',
swapPurchaser: '0x440d9D4E66d39bb28FB58729Cb4D3ead2A595591',
tokens: [
{
address: '0xef4229c8c3250C675F21BCefa42f58EfbfF6002a',
Expand Down
1 change: 0 additions & 1 deletion packages/networks/src/networks/goerli.ts
Expand Up @@ -86,7 +86,6 @@ export const goerli: NetworkConfig = {
'https://api.studio.thegraph.com/query/65299/unlock-protocol-goerli/version/latest',
studioName: 'unlock-protocol-goerli',
},
swapPurchaser: '0x49aD0039B30De002d4C27A6E8Fc026c7e23d083C',
tokens: [
{
address: '0x07865c6E87B9F70255377e024ace6630C1Eaa37F',
Expand Down
1 change: 0 additions & 1 deletion packages/networks/src/networks/mainnet.ts
Expand Up @@ -75,7 +75,6 @@ export const mainnet: NetworkConfig = {
'https://api.studio.thegraph.com/query/65299/unlock-protocol-mainnet/version/latest',
studioName: 'unlock-protocol-mainnet',
},
swapPurchaser: '0x02415541c7F4c976722493181cFdb0b46E1c94fb',
tokens: [
{
address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/mumbai.ts
Expand Up @@ -66,7 +66,7 @@ export const mumbai: NetworkConfig = {
'https://api.studio.thegraph.com/query/65299/unlock-protocol-mumbai/version/latest',
studioName: 'unlock-protocol-mumbai',
},
swapPurchaser: '0x302E9D970A657B42c1C124C69f3a1c1575CB4AD3',
swapPurchaser: '0xD7477B7c0CdA4204Cf860e4c27486061b15a5AC3',
tokens: [
{
address: '0x0FA8781a83E46826621b3BC094Ea2A0212e71B23',
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/optimism.ts
Expand Up @@ -85,7 +85,7 @@ export const optimism: NetworkConfig = {
'https://api.studio.thegraph.com/query/65299/unlock-protocol-optimism/version/latest',
studioName: 'unlock-protocol-optimism',
},
swapPurchaser: '0x72381052e4F7765A00a403891420BF75876c75bB',
swapPurchaser: '0x1bd356194d97297F77e081fFFAB97b57297E93e4',
tokens: [
{
address: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607',
Expand Down
1 change: 0 additions & 1 deletion packages/networks/src/networks/polygon.ts
Expand Up @@ -91,7 +91,6 @@ export const polygon: NetworkConfig = {
networkName: 'matic',
studioName: 'unlock-protocol-polygon',
},
swapPurchaser: '0x33aC9CAE1Cd9CBB191116607f564F7381d81BAD9',
tokens: [
{
address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/src/networks/sepolia.ts
Expand Up @@ -84,7 +84,7 @@ export const sepolia: NetworkConfig = {
networkName: 'sepolia',
studioName: 'unlock-protocol-sepolia',
},
swapPurchaser: '0x580A4a5a9612371e3832c4559026B9Ee3b23Cc11',
swapPurchaser: '0x692EFe2b44a531013A558E595C5dCf37DB2e4B94',
tokens: [
{
address: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9',
Expand Down
2 changes: 2 additions & 0 deletions packages/unlock-js/src/PublicLock/v10/extendKey.js
Expand Up @@ -131,6 +131,7 @@ export default async function (
? unlockSwapPurchaserContract?.estimateGas?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down Expand Up @@ -165,6 +166,7 @@ export default async function (
? unlockSwapPurchaserContract?.populateTransaction?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down
2 changes: 2 additions & 0 deletions packages/unlock-js/src/PublicLock/v10/purchaseKeys.js
Expand Up @@ -94,6 +94,7 @@ export default async function (options, transactionOptions = {}, callback) {
? unlockSwapPurchaserContract?.estimateGas?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
totalPrice,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down Expand Up @@ -128,6 +129,7 @@ export default async function (options, transactionOptions = {}, callback) {
? unlockSwapPurchaserContract?.populateTransaction?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
totalPrice,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down
1 change: 1 addition & 0 deletions packages/unlock-js/src/PublicLock/v4/purchaseKey.js
Expand Up @@ -83,6 +83,7 @@ export default async function (
? unlockSwapPurchaserContract?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down
2 changes: 2 additions & 0 deletions packages/unlock-js/src/PublicLock/v6/purchaseKey.js
Expand Up @@ -124,6 +124,7 @@ export default async function (
? unlockSwapPurchaserContract?.estimateGas?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down Expand Up @@ -159,6 +160,7 @@ export default async function (
? unlockSwapPurchaserContract?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down
2 changes: 2 additions & 0 deletions packages/unlock-js/src/PublicLock/v9/purchaseKey.js
Expand Up @@ -124,6 +124,7 @@ export default async function (
? unlockSwapPurchaserContract?.estimateGas?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down Expand Up @@ -161,6 +162,7 @@ export default async function (
? unlockSwapPurchaserContract?.swapAndCall(
lockAddress,
swap.srcTokenAddress || ZERO,
actualAmount,
swap.amountInMax,
swap.uniswapRouter,
swap.swapCallData,
Expand Down
53 changes: 52 additions & 1 deletion packages/unlock-js/src/abis/UnlockSwapPurchaserABI.ts
Copy link
Member

Choose a reason for hiding this comment

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

maybe get this from contracts package?

@@ -1,3 +1,54 @@
// TODO: import from package!
// import { networks } from '@unlock-protocol/contracts'

export const UnlockSwapPurchaserABI = [
`function swapAndCall(address lock, address srcToken, uint amountInMax,address uniswapRouter, bytes memory swapCalldata, bytes memory callData) public payable returns(bytes memory)`,
{
inputs: [
{
internalType: 'address',
name: 'lock',
type: 'address',
},
{
internalType: 'address',
name: 'srcToken',
type: 'address',
},
{
internalType: 'uint256',
name: 'keyPrice',
type: 'uint256',
},
{
internalType: 'uint256',
name: 'amountInMax',
type: 'uint256',
},
{
internalType: 'address',
name: 'uniswapRouter',
type: 'address',
},
{
internalType: 'bytes',
name: 'swapCalldata',
type: 'bytes',
},
{
internalType: 'bytes',
name: 'callData',
type: 'bytes',
},
],
name: 'swapAndCall',
outputs: [
{
internalType: 'bytes',
name: '',
type: 'bytes',
},
],
stateMutability: 'payable',
type: 'function',
},
]