Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
Gas Tokens in Bridges (#2523)
Browse files Browse the repository at this point in the history
* Gas Tokens in Bridges

* Added freesGasTokensFromCollector.

To handle the case where GST2 is being traded and the balanceOf checks become confusing

* Update CHANGELOGs
  • Loading branch information
dekz authored Mar 26, 2020
1 parent 99b0a95 commit 568e9be
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 2 deletions.
4 changes: 4 additions & 0 deletions contracts/asset-proxy/CHANGELOG.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
]
},
Expand Down
5 changes: 4 additions & 1 deletion contracts/asset-proxy/contracts/src/bridges/CurveBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ 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
// solhint-disable space-after-comma
contract CurveBridge is
IERC20Bridge,
IWallet,
DeploymentConstants
DeploymentConstants,
MixinGasToken
{
struct CurveBridgeData {
address curveAddress;
Expand All @@ -60,6 +62,7 @@ contract CurveBridge is
bytes calldata bridgeData
)
external
freesGasTokensFromCollector
returns (bytes4 success)
{
// Decode the bridge data to get the Curve metadata.
Expand Down
55 changes: 55 additions & 0 deletions contracts/asset-proxy/contracts/src/bridges/MixinGasToken.sol
Original file line number Diff line number Diff line change
@@ -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 changes: 40 additions & 0 deletions contracts/asset-proxy/contracts/src/interfaces/IGasToken.sol
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 1 addition & 1 deletion contracts/asset-proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
4 changes: 4 additions & 0 deletions contracts/asset-proxy/src/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions contracts/asset-proxy/src/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 4 additions & 0 deletions contracts/asset-proxy/test/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions contracts/asset-proxy/test/wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 4 additions & 0 deletions contracts/asset-proxy/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
9 changes: 9 additions & 0 deletions contracts/utils/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
28 changes: 28 additions & 0 deletions contracts/utils/contracts/src/DeploymentConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
}

0 comments on commit 568e9be

Please sign in to comment.