-
Notifications
You must be signed in to change notification settings - Fork 672
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
New TokenPaymaster #286
New TokenPaymaster #286
Changes from 1 commit
eabd560
e814e97
70ce950
82bf877
d78b712
664e65f
e39e9a3
23312c6
06c130c
5e0cca2
03efff5
5a4f340
dd896a0
aae7c9a
63cf750
39a1e41
a047984
6ac12fe
c2c775d
41ee2ec
28916ad
821ada7
d461522
36633a5
eeaf42a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,7 +67,7 @@ abstract contract OracleHelper { | |
|
||
function _setOracleConfiguration( | ||
OracleHelperConfig memory _oracleHelperConfig | ||
) internal { | ||
) private { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leaving this method (called only from constructor) means that we still pay the SLOAD when using these parameters. Currently, the paymaster uses 15 slots (14, if we exclude "owner") |
||
oracleHelperConfig = _oracleHelperConfig; | ||
require(_oracleHelperConfig.priceUpdateThreshold <= 1e6, "TPM: update threshold too high"); | ||
tokenOracleDecimalPower = 10 ** oracleHelperConfig.tokenOracle.decimals(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ import { ethers } from 'hardhat' | |
import { AddressZero } from '../testutils' | ||
|
||
import { | ||
TestERC20, | ||
TestERC20__factory, | ||
TestOracle2, | ||
TestOracle2__factory, | ||
|
@@ -55,7 +56,7 @@ const sampleResponses = { | |
} | ||
|
||
// note: direct or reverse designations are quite arbitrary | ||
describe.only('OracleHelper', function () { | ||
describe('OracleHelper', function () { | ||
function testOracleFiguredPriceOut (): void { | ||
it('should figure out the correct price', async function () { | ||
await testEnv.paymaster.updateCachedPrice(true) | ||
|
@@ -87,8 +88,12 @@ describe.only('OracleHelper', function () { | |
} | ||
|
||
interface TestEnv { | ||
owner: string | ||
expectedPrice: string | ||
expectedTokensPerEtherCalculated: string | ||
tokenPaymasterConfig: TokenPaymaster.TokenPaymasterConfigStruct | ||
uniswapHelperConfig: UniswapHelperNamespace.UniswapHelperConfigStruct | ||
token: TestERC20 | ||
paymaster: TokenPaymaster | ||
tokenOracle: TestOracle2 | ||
nativeAssetOracle: TestOracle2 | ||
|
@@ -99,15 +104,15 @@ describe.only('OracleHelper', function () { | |
|
||
before(async function () { | ||
const ethersSigner = ethers.provider.getSigner() | ||
const owner = await ethersSigner.getAddress() | ||
testEnv.owner = await ethersSigner.getAddress() | ||
|
||
const tokenPaymasterConfig: TokenPaymaster.TokenPaymasterConfigStruct = { | ||
testEnv.tokenPaymasterConfig = { | ||
priceMaxAge: 86400, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^^ remove "only" from |
||
refundPostopCost: 40000, | ||
minEntryPointBalance: 0, | ||
priceMarkup: priceDenominator.mul(19).div(10) // 190% | ||
} | ||
const uniswapHelperConfig: UniswapHelperNamespace.UniswapHelperConfigStruct = { | ||
testEnv.uniswapHelperConfig = { | ||
minSwapAmount: 1, | ||
slippage: 5, | ||
uniswapPoolFee: 3 | ||
|
@@ -117,21 +122,21 @@ describe.only('OracleHelper', function () { | |
testEnv.tokenOracle = await new TestOracle2__factory(ethersSigner).deploy(1, 0) | ||
testEnv.nativeAssetOracle = await new TestOracle2__factory(ethersSigner).deploy(1, 0) | ||
|
||
const token = await new TestERC20__factory(ethersSigner).deploy(18) | ||
testEnv.token = await new TestERC20__factory(ethersSigner).deploy(18) | ||
|
||
testEnv.paymaster = await new TokenPaymaster__factory(ethersSigner).deploy( | ||
token.address, | ||
testEnv.token.address, | ||
AddressZero, | ||
AddressZero, | ||
owner, // cannot approve to AddressZero | ||
tokenPaymasterConfig, | ||
testEnv.owner, // cannot approve to AddressZero | ||
testEnv.tokenPaymasterConfig, | ||
getOracleConfig({ | ||
nativeOracleReverse: false, | ||
tokenOracleReverse: false, | ||
tokenToNativeOracle: false | ||
}), | ||
uniswapHelperConfig, | ||
owner | ||
testEnv.uniswapHelperConfig, | ||
testEnv.owner | ||
) | ||
}) | ||
|
||
|
@@ -156,11 +161,21 @@ describe.only('OracleHelper', function () { | |
.div(res.answer) | ||
.toString() | ||
|
||
await testEnv.paymaster.setOracleConfiguration(getOracleConfig({ | ||
tokenToNativeOracle: true, | ||
tokenOracleReverse: false, | ||
nativeOracleReverse: false | ||
})) | ||
const ethersSigner = ethers.provider.getSigner() | ||
testEnv.paymaster = await new TokenPaymaster__factory(ethersSigner).deploy( | ||
testEnv.token.address, | ||
AddressZero, | ||
AddressZero, | ||
testEnv.owner, // cannot approve to AddressZero | ||
testEnv.tokenPaymasterConfig, | ||
getOracleConfig({ | ||
tokenToNativeOracle: true, | ||
tokenOracleReverse: false, | ||
nativeOracleReverse: false | ||
}), | ||
testEnv.uniswapHelperConfig, | ||
testEnv.owner | ||
) | ||
}) | ||
|
||
testOracleFiguredPriceOut() | ||
|
@@ -197,11 +212,21 @@ describe.only('OracleHelper', function () { | |
// sanity check for the price calculation - use direct price and cached-like reverse price | ||
assert.equal(expectedTokensPerEtherCalculated.toString(), testEnv.expectedTokensPerEtherCalculated.toString()) | ||
|
||
await testEnv.paymaster.setOracleConfiguration(getOracleConfig({ | ||
tokenToNativeOracle: true, | ||
tokenOracleReverse: true, | ||
nativeOracleReverse: false | ||
})) | ||
const ethersSigner = ethers.provider.getSigner() | ||
testEnv.paymaster = await new TokenPaymaster__factory(ethersSigner).deploy( | ||
testEnv.token.address, | ||
AddressZero, | ||
AddressZero, | ||
testEnv.owner, // cannot approve to AddressZero | ||
testEnv.tokenPaymasterConfig, | ||
getOracleConfig({ | ||
tokenToNativeOracle: true, | ||
tokenOracleReverse: true, | ||
nativeOracleReverse: false | ||
}), | ||
testEnv.uniswapHelperConfig, | ||
testEnv.owner | ||
) | ||
}) | ||
testOracleFiguredPriceOut() | ||
}) | ||
|
@@ -217,12 +242,21 @@ describe.only('OracleHelper', function () { | |
await testEnv.nativeAssetOracle.setPrice(resNative.answer) // $1,817.65 | ||
await testEnv.nativeAssetOracle.setDecimals(resNative.decimals) | ||
|
||
await testEnv.paymaster.setOracleConfiguration(getOracleConfig({ | ||
tokenToNativeOracle: false, | ||
tokenOracleReverse: false, | ||
nativeOracleReverse: false | ||
})) | ||
|
||
const ethersSigner = ethers.provider.getSigner() | ||
testEnv.paymaster = await new TokenPaymaster__factory(ethersSigner).deploy( | ||
testEnv.token.address, | ||
AddressZero, | ||
AddressZero, | ||
testEnv.owner, // cannot approve to AddressZero | ||
testEnv.tokenPaymasterConfig, | ||
getOracleConfig({ | ||
tokenToNativeOracle: false, | ||
tokenOracleReverse: false, | ||
nativeOracleReverse: false | ||
}), | ||
testEnv.uniswapHelperConfig, | ||
testEnv.owner | ||
) | ||
// note: oracle decimals are same and cancel each other out | ||
testEnv.expectedPrice = | ||
priceDenominator | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean router swapping cost is dumped on to the users?
since it is conditional postOp cost would change
if not user who is paying for this computation - paymaster's gas deposit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A single user should not get stuck with the bill for the Paymaster's swap operation on its own.
I am not sure but I think what we should do is to set the
POSTOP_COST
parameter such that it kind of spreads the cost of these periodic swaps over all other transactions.Of course this way it may end up accumulating some loss or profit over time if left completely unattended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If paymaster is always charging premium, POSTOP_COST can just be everything unaccounted on-chain on entry point and postOp - swap executionGas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@livingrockrises
A paymaster is expected to set
refundPostopCost
to actual cost of postOp, with faction of the cost of the uniswap, since the swap is expected to happen only every "N" transaction.