Gas Tokens in Bridges (#2523)
* Gas Tokens in Bridges * Added freesGasTokensFromCollector. To handle the case where GST2 is being traded and the balanceOf checks become confusing * Update CHANGELOGs
This commit is contained in:
parent
99b0a95f8a
commit
568e9be07e
@ -13,6 +13,10 @@
|
||||
{
|
||||
"note": "Change names of `ERC20BridgeTransfer` args to be less ambiguous.",
|
||||
"pr": 2524
|
||||
},
|
||||
{
|
||||
"note": "Added `MixinGasToken` allowing Gas Tokens to be freed",
|
||||
"pr": 2523
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -26,6 +26,7 @@ import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "../interfaces/IERC20Bridge.sol";
|
||||
import "../interfaces/ICurve.sol";
|
||||
import "./MixinGasToken.sol";
|
||||
|
||||
|
||||
// solhint-disable not-rely-on-time
|
||||
@ -33,7 +34,8 @@ import "../interfaces/ICurve.sol";
|
||||
contract CurveBridge is
|
||||
IERC20Bridge,
|
||||
IWallet,
|
||||
DeploymentConstants
|
||||
DeploymentConstants,
|
||||
MixinGasToken
|
||||
{
|
||||
struct CurveBridgeData {
|
||||
address curveAddress;
|
||||
@ -60,6 +62,7 @@ contract CurveBridge is
|
||||
bytes calldata bridgeData
|
||||
)
|
||||
external
|
||||
freesGasTokensFromCollector
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Decode the bridge data to get the Curve metadata.
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.16;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "../interfaces/IGasToken.sol";
|
||||
|
||||
|
||||
contract MixinGasToken is
|
||||
DeploymentConstants
|
||||
{
|
||||
|
||||
/// @dev Frees gas tokens based on the amount of gas consumed in the function
|
||||
modifier freesGasTokens {
|
||||
uint256 gasBefore = gasleft();
|
||||
_;
|
||||
IGasToken gst = IGasToken(_getGstAddress());
|
||||
if (address(gst) != address(0)) {
|
||||
// (gasUsed + FREE_BASE) / (2 * REIMBURSE - FREE_TOKEN)
|
||||
// 14154 24000 6870
|
||||
uint256 value = (gasBefore - gasleft() + 14154) / 41130;
|
||||
gst.freeUpTo(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Frees gas tokens using the balance of `from`. Amount freed is based
|
||||
/// on the gas consumed in the function
|
||||
modifier freesGasTokensFromCollector() {
|
||||
uint256 gasBefore = gasleft();
|
||||
_;
|
||||
IGasToken gst = IGasToken(_getGstAddress());
|
||||
if (address(gst) != address(0)) {
|
||||
// (gasUsed + FREE_BASE) / (2 * REIMBURSE - FREE_TOKEN)
|
||||
// 14154 24000 6870
|
||||
uint256 value = (gasBefore - gasleft() + 14154) / 41130;
|
||||
gst.freeFromUpTo(_getGstCollectorAddress(), value);
|
||||
}
|
||||
}
|
||||
}
|
40
contracts/asset-proxy/contracts/src/interfaces/IGasToken.sol
Normal file
40
contracts/asset-proxy/contracts/src/interfaces/IGasToken.sol
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.15;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
|
||||
|
||||
contract IGasToken is IERC20Token {
|
||||
|
||||
/// @dev Frees up to `value` sub-tokens
|
||||
/// @param value The amount of tokens to free
|
||||
/// @return How many tokens were freed
|
||||
function freeUpTo(uint256 value) external returns (uint256 freed);
|
||||
|
||||
/// @dev Frees up to `value` sub-tokens owned by `from`
|
||||
/// @param from The owner of tokens to spend
|
||||
/// @param value The amount of tokens to free
|
||||
/// @return How many tokens were freed
|
||||
function freeFromUpTo(address from, uint256 value) external returns (uint256 freed);
|
||||
|
||||
/// @dev Mints `value` amount of tokens
|
||||
/// @param value The amount of tokens to mint
|
||||
function mint(uint256 value) external;
|
||||
}
|
@ -38,7 +38,7 @@
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./test/generated-artifacts/@(ChaiBridge|CurveBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
"abis": "./test/generated-artifacts/@(ChaiBridge|CurveBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IUniswapExchange|IUniswapExchangeFactory|KyberBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|UniswapBridge).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
@ -23,12 +23,14 @@ import * as IDydx from '../generated-artifacts/IDydx.json';
|
||||
import * as IDydxBridge from '../generated-artifacts/IDydxBridge.json';
|
||||
import * as IERC20Bridge from '../generated-artifacts/IERC20Bridge.json';
|
||||
import * as IEth2Dai from '../generated-artifacts/IEth2Dai.json';
|
||||
import * as IGasToken from '../generated-artifacts/IGasToken.json';
|
||||
import * as IKyberNetworkProxy from '../generated-artifacts/IKyberNetworkProxy.json';
|
||||
import * as IUniswapExchange from '../generated-artifacts/IUniswapExchange.json';
|
||||
import * as IUniswapExchangeFactory from '../generated-artifacts/IUniswapExchangeFactory.json';
|
||||
import * as KyberBridge from '../generated-artifacts/KyberBridge.json';
|
||||
import * as MixinAssetProxyDispatcher from '../generated-artifacts/MixinAssetProxyDispatcher.json';
|
||||
import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json';
|
||||
import * as MixinGasToken from '../generated-artifacts/MixinGasToken.json';
|
||||
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
|
||||
import * as Ownable from '../generated-artifacts/Ownable.json';
|
||||
import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json';
|
||||
@ -55,6 +57,7 @@ export const artifacts = {
|
||||
DydxBridge: DydxBridge as ContractArtifact,
|
||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||
KyberBridge: KyberBridge as ContractArtifact,
|
||||
MixinGasToken: MixinGasToken as ContractArtifact,
|
||||
UniswapBridge: UniswapBridge as ContractArtifact,
|
||||
IAssetData: IAssetData as ContractArtifact,
|
||||
IAssetProxy: IAssetProxy as ContractArtifact,
|
||||
@ -66,6 +69,7 @@ export const artifacts = {
|
||||
IDydxBridge: IDydxBridge as ContractArtifact,
|
||||
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
||||
IEth2Dai: IEth2Dai as ContractArtifact,
|
||||
IGasToken: IGasToken as ContractArtifact,
|
||||
IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact,
|
||||
IUniswapExchange: IUniswapExchange as ContractArtifact,
|
||||
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
|
||||
|
@ -21,12 +21,14 @@ export * from '../generated-wrappers/i_dydx';
|
||||
export * from '../generated-wrappers/i_dydx_bridge';
|
||||
export * from '../generated-wrappers/i_erc20_bridge';
|
||||
export * from '../generated-wrappers/i_eth2_dai';
|
||||
export * from '../generated-wrappers/i_gas_token';
|
||||
export * from '../generated-wrappers/i_kyber_network_proxy';
|
||||
export * from '../generated-wrappers/i_uniswap_exchange';
|
||||
export * from '../generated-wrappers/i_uniswap_exchange_factory';
|
||||
export * from '../generated-wrappers/kyber_bridge';
|
||||
export * from '../generated-wrappers/mixin_asset_proxy_dispatcher';
|
||||
export * from '../generated-wrappers/mixin_authorizable';
|
||||
export * from '../generated-wrappers/mixin_gas_token';
|
||||
export * from '../generated-wrappers/multi_asset_proxy';
|
||||
export * from '../generated-wrappers/ownable';
|
||||
export * from '../generated-wrappers/static_call_proxy';
|
||||
|
@ -23,12 +23,14 @@ import * as IDydx from '../test/generated-artifacts/IDydx.json';
|
||||
import * as IDydxBridge from '../test/generated-artifacts/IDydxBridge.json';
|
||||
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
|
||||
import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json';
|
||||
import * as IGasToken from '../test/generated-artifacts/IGasToken.json';
|
||||
import * as IKyberNetworkProxy from '../test/generated-artifacts/IKyberNetworkProxy.json';
|
||||
import * as IUniswapExchange from '../test/generated-artifacts/IUniswapExchange.json';
|
||||
import * as IUniswapExchangeFactory from '../test/generated-artifacts/IUniswapExchangeFactory.json';
|
||||
import * as KyberBridge from '../test/generated-artifacts/KyberBridge.json';
|
||||
import * as MixinAssetProxyDispatcher from '../test/generated-artifacts/MixinAssetProxyDispatcher.json';
|
||||
import * as MixinAuthorizable from '../test/generated-artifacts/MixinAuthorizable.json';
|
||||
import * as MixinGasToken from '../test/generated-artifacts/MixinGasToken.json';
|
||||
import * as MultiAssetProxy from '../test/generated-artifacts/MultiAssetProxy.json';
|
||||
import * as Ownable from '../test/generated-artifacts/Ownable.json';
|
||||
import * as StaticCallProxy from '../test/generated-artifacts/StaticCallProxy.json';
|
||||
@ -55,6 +57,7 @@ export const artifacts = {
|
||||
DydxBridge: DydxBridge as ContractArtifact,
|
||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||
KyberBridge: KyberBridge as ContractArtifact,
|
||||
MixinGasToken: MixinGasToken as ContractArtifact,
|
||||
UniswapBridge: UniswapBridge as ContractArtifact,
|
||||
IAssetData: IAssetData as ContractArtifact,
|
||||
IAssetProxy: IAssetProxy as ContractArtifact,
|
||||
@ -66,6 +69,7 @@ export const artifacts = {
|
||||
IDydxBridge: IDydxBridge as ContractArtifact,
|
||||
IERC20Bridge: IERC20Bridge as ContractArtifact,
|
||||
IEth2Dai: IEth2Dai as ContractArtifact,
|
||||
IGasToken: IGasToken as ContractArtifact,
|
||||
IKyberNetworkProxy: IKyberNetworkProxy as ContractArtifact,
|
||||
IUniswapExchange: IUniswapExchange as ContractArtifact,
|
||||
IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact,
|
||||
|
@ -21,12 +21,14 @@ export * from '../test/generated-wrappers/i_dydx';
|
||||
export * from '../test/generated-wrappers/i_dydx_bridge';
|
||||
export * from '../test/generated-wrappers/i_erc20_bridge';
|
||||
export * from '../test/generated-wrappers/i_eth2_dai';
|
||||
export * from '../test/generated-wrappers/i_gas_token';
|
||||
export * from '../test/generated-wrappers/i_kyber_network_proxy';
|
||||
export * from '../test/generated-wrappers/i_uniswap_exchange';
|
||||
export * from '../test/generated-wrappers/i_uniswap_exchange_factory';
|
||||
export * from '../test/generated-wrappers/kyber_bridge';
|
||||
export * from '../test/generated-wrappers/mixin_asset_proxy_dispatcher';
|
||||
export * from '../test/generated-wrappers/mixin_authorizable';
|
||||
export * from '../test/generated-wrappers/mixin_gas_token';
|
||||
export * from '../test/generated-wrappers/multi_asset_proxy';
|
||||
export * from '../test/generated-wrappers/ownable';
|
||||
export * from '../test/generated-wrappers/static_call_proxy';
|
||||
|
@ -21,12 +21,14 @@
|
||||
"generated-artifacts/IDydxBridge.json",
|
||||
"generated-artifacts/IERC20Bridge.json",
|
||||
"generated-artifacts/IEth2Dai.json",
|
||||
"generated-artifacts/IGasToken.json",
|
||||
"generated-artifacts/IKyberNetworkProxy.json",
|
||||
"generated-artifacts/IUniswapExchange.json",
|
||||
"generated-artifacts/IUniswapExchangeFactory.json",
|
||||
"generated-artifacts/KyberBridge.json",
|
||||
"generated-artifacts/MixinAssetProxyDispatcher.json",
|
||||
"generated-artifacts/MixinAuthorizable.json",
|
||||
"generated-artifacts/MixinGasToken.json",
|
||||
"generated-artifacts/MultiAssetProxy.json",
|
||||
"generated-artifacts/Ownable.json",
|
||||
"generated-artifacts/StaticCallProxy.json",
|
||||
@ -56,12 +58,14 @@
|
||||
"test/generated-artifacts/IDydxBridge.json",
|
||||
"test/generated-artifacts/IERC20Bridge.json",
|
||||
"test/generated-artifacts/IEth2Dai.json",
|
||||
"test/generated-artifacts/IGasToken.json",
|
||||
"test/generated-artifacts/IKyberNetworkProxy.json",
|
||||
"test/generated-artifacts/IUniswapExchange.json",
|
||||
"test/generated-artifacts/IUniswapExchangeFactory.json",
|
||||
"test/generated-artifacts/KyberBridge.json",
|
||||
"test/generated-artifacts/MixinAssetProxyDispatcher.json",
|
||||
"test/generated-artifacts/MixinAuthorizable.json",
|
||||
"test/generated-artifacts/MixinGasToken.json",
|
||||
"test/generated-artifacts/MultiAssetProxy.json",
|
||||
"test/generated-artifacts/Ownable.json",
|
||||
"test/generated-artifacts/StaticCallProxy.json",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "4.5.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added `GST_ADDRESS` and `GST_COLLECTOR_ADDRESS`",
|
||||
"pr": 2523
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1583220306,
|
||||
"version": "4.4.3",
|
||||
|
@ -54,6 +54,14 @@ contract DeploymentConstants {
|
||||
address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
/// @dev Mainnet address of the dYdX contract.
|
||||
address constant private DYDX_ADDRESS = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e;
|
||||
/// @dev Mainnet address of the GST2 contract
|
||||
address constant private GST_ADDRESS = 0x0000000000b3F879cb30FE243b4Dfee438691c04;
|
||||
/// @dev Mainnet address of the GST Collector
|
||||
address constant private GST_COLLECTOR_ADDRESS = address(0);
|
||||
// /// @dev Kovan address of the GST2 contract
|
||||
// address constant private GST_ADDRESS = address(0);
|
||||
// /// @dev Kovan address of the GST Collector
|
||||
// address constant private GST_COLLECTOR_ADDRESS = address(0);
|
||||
|
||||
/// @dev Overridable way to get the `KyberNetworkProxy` address.
|
||||
/// @return kyberAddress The `IKyberNetworkProxy` address.
|
||||
@ -144,4 +152,24 @@ contract DeploymentConstants {
|
||||
{
|
||||
return DYDX_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the GST2 contract address.
|
||||
/// @return gst The GST contract.
|
||||
function _getGstAddress()
|
||||
internal
|
||||
view
|
||||
returns (address gst)
|
||||
{
|
||||
return GST_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the GST Collector address.
|
||||
/// @return collector The GST collector address.
|
||||
function _getGstCollectorAddress()
|
||||
internal
|
||||
view
|
||||
returns (address collector)
|
||||
{
|
||||
return GST_COLLECTOR_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user