// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../utils/EnumerableSet.sol";
import"../utils/Address.sol";
import"../utils/Context.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/abstractcontractAccessControlisContext{
usingEnumerableSetforEnumerableSet.AddressSet;
usingAddressforaddress;
structRoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32=> RoleData) private _roles;
bytes32publicconstant DEFAULT_ADMIN_ROLE =0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/eventRoleAdminChanged(bytes32indexed role, bytes32indexed previousAdminRole, bytes32indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/eventRoleGranted(bytes32indexed role, addressindexed account, addressindexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/eventRoleRevoked(bytes32indexed role, addressindexed account, addressindexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/functionhasRole(bytes32 role, address account) publicviewreturns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/functiongetRoleMemberCount(bytes32 role) publicviewreturns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/functiongetRoleMember(bytes32 role, uint256 index) publicviewreturns (address) {
return _roles[role].members.at(index);
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/functiongetRoleAdmin(bytes32 role) publicviewreturns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/functiongrantRole(bytes32 role, address account) publicvirtual{
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/functionrevokeRole(bytes32 role, address account) publicvirtual{
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/functionrenounceRole(bytes32 role, address account) publicvirtual{
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/function_setupRole(bytes32 role, address account) internalvirtual{
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/function_setRoleAdmin(bytes32 role, bytes32 adminRole) internalvirtual{
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function_grantRole(bytes32 role, address account) private{
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function_revokeRole(bytes32 role, address account) private{
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}
Contract Source Code
File 2 of 71: AccessControlUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../utils/EnumerableSetUpgradeable.sol";
import"../utils/AddressUpgradeable.sol";
import"../utils/ContextUpgradeable.sol";
import"../proxy/Initializable.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/abstractcontractAccessControlUpgradeableisInitializable, ContextUpgradeable{
function__AccessControl_init() internalinitializer{
__Context_init_unchained();
__AccessControl_init_unchained();
}
function__AccessControl_init_unchained() internalinitializer{
}
usingEnumerableSetUpgradeableforEnumerableSetUpgradeable.AddressSet;
usingAddressUpgradeableforaddress;
structRoleData {
EnumerableSetUpgradeable.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32=> RoleData) private _roles;
bytes32publicconstant DEFAULT_ADMIN_ROLE =0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/eventRoleAdminChanged(bytes32indexed role, bytes32indexed previousAdminRole, bytes32indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/eventRoleGranted(bytes32indexed role, addressindexed account, addressindexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/eventRoleRevoked(bytes32indexed role, addressindexed account, addressindexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/functionhasRole(bytes32 role, address account) publicviewreturns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/functiongetRoleMemberCount(bytes32 role) publicviewreturns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/functiongetRoleMember(bytes32 role, uint256 index) publicviewreturns (address) {
return _roles[role].members.at(index);
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/functiongetRoleAdmin(bytes32 role) publicviewreturns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/functiongrantRole(bytes32 role, address account) publicvirtual{
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/functionrevokeRole(bytes32 role, address account) publicvirtual{
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/functionrenounceRole(bytes32 role, address account) publicvirtual{
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/function_setupRole(bytes32 role, address account) internalvirtual{
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/function_setRoleAdmin(bytes32 role, bytes32 adminRole) internalvirtual{
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function_grantRole(bytes32 role, address account) private{
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function_revokeRole(bytes32 role, address account) private{
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
uint256[49] private __gap;
}
Contract Source Code
File 3 of 71: Address.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.2 <0.8.0;/**
* @dev Collection of functions related to the address type
*/libraryAddress{
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/functionisContract(address account) internalviewreturns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in// construction, since the code is only stored at the end of the// constructor execution.uint256 size;
// solhint-disable-next-line no-inline-assemblyassembly { size :=extcodesize(account) }
return size >0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/functionsendValue(addresspayable recipient, uint256 amount) internal{
require(address(this).balance>= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/functionfunctionCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCall(address target, bytesmemory data, stringmemory errorMessage) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target, bytesmemory data, uint256 value) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target, bytesmemory data, uint256 value, stringmemory errorMessage) internalreturns (bytesmemory) {
require(address(this).balance>= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target, bytesmemory data) internalviewreturns (bytesmemory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target, bytesmemory data, stringmemory errorMessage) internalviewreturns (bytesmemory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/functionfunctionDelegateCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/functionfunctionDelegateCall(address target, bytesmemory data, stringmemory errorMessage) internalreturns (bytesmemory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function_verifyCallResult(bool success, bytesmemory returndata, stringmemory errorMessage) privatepurereturns(bytesmemory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if presentif (returndata.length>0) {
// The easiest way to bubble the revert reason is using memory via assembly// solhint-disable-next-line no-inline-assemblyassembly {
let returndata_size :=mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
Contract Source Code
File 4 of 71: AddressUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.2 <0.8.0;/**
* @dev Collection of functions related to the address type
*/libraryAddressUpgradeable{
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/functionisContract(address account) internalviewreturns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in// construction, since the code is only stored at the end of the// constructor execution.uint256 size;
// solhint-disable-next-line no-inline-assemblyassembly { size :=extcodesize(account) }
return size >0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/functionsendValue(addresspayable recipient, uint256 amount) internal{
require(address(this).balance>= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/functionfunctionCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCall(address target, bytesmemory data, stringmemory errorMessage) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target, bytesmemory data, uint256 value) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target, bytesmemory data, uint256 value, stringmemory errorMessage) internalreturns (bytesmemory) {
require(address(this).balance>= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target, bytesmemory data) internalviewreturns (bytesmemory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target, bytesmemory data, stringmemory errorMessage) internalviewreturns (bytesmemory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function_verifyCallResult(bool success, bytesmemory returndata, stringmemory errorMessage) privatepurereturns(bytesmemory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if presentif (returndata.length>0) {
// The easiest way to bubble the revert reason is using memory via assembly// solhint-disable-next-line no-inline-assemblyassembly {
let returndata_size :=mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
Contract Source Code
File 5 of 71: AggregatorV3Interface.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0;interfaceAggregatorV3Interface{
functiondecimals() externalviewreturns (uint8);
functiondescription() externalviewreturns (stringmemory);
functionversion() externalviewreturns (uint256);
// getRoundData and latestRoundData should both raise "No data present"// if they do not have data to report, instead of returning unset values// which could be misinterpreted as actual reported values.functiongetRoundData(uint80 _roundId)
externalviewreturns (uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
functionlatestRoundData()
externalviewreturns (uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;import"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import"@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import"@openzeppelin/contracts/math/SafeMath.sol";
import"@openzeppelin/contracts/utils/Address.sol";
import"../interfaces/balancer/IBalancerPool.sol";
contractBalancerController{
usingSafeERC20forIERC20;
usingAddressforaddress;
usingAddressforaddresspayable;
usingSafeMathforuint256;
functiondeploy(address poolAddress,
IERC20[] calldata tokens,
uint256[] calldata amounts,
bytescalldata data
) external{
require(tokens.length== amounts.length, "TOKEN_AMOUNTS_COUNT_MISMATCH");
require(tokens.length>0, "TOKENS_AMOUNTS_NOT_PROVIDED");
for (uint256 i =0; i < tokens.length; i++) {
_approve(tokens[i], poolAddress, amounts[i]);
}
//Notes:// - If your pool is eligible for weekly BAL rewards, they will be distributed to your LPs automatically// - If you contribute significant long-term liquidity to the platform, you can apply to have smart contract deployment gas costs reimbursed from the Balancer Ecosystem fund// - The pool is the LP token, All pools in Balancer are also ERC20 tokens known as BPTs \(Balancer Pool Tokens\)
(uint256 poolAmountOut, uint256[] memory maxAmountsIn) =abi.decode(data, (uint256, uint256[]));
IBalancerPool(poolAddress).joinPool(poolAmountOut, maxAmountsIn);
}
functionwithdraw(address poolAddress, bytescalldata data) external{
(uint256 poolAmountIn, uint256[] memory minAmountsOut) =abi.decode(data, (uint256, uint256[]));
_approve(IERC20(poolAddress), poolAddress, poolAmountIn);
IBalancerPool(poolAddress).exitPool(poolAmountIn, minAmountsOut);
}
function_approve(
IERC20 token,
address poolAddress,
uint256 amount
) internal{
uint256 currentAllowance = token.allowance(address(this), poolAddress);
if (currentAllowance < amount) {
token.safeIncreaseAllowance(poolAddress, type(uint256).max.sub(currentAllowance));
}
}
}
Contract Source Code
File 8 of 71: Context.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (addresspayable) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytesmemory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691returnmsg.data;
}
}
Contract Source Code
File 9 of 71: ContextUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../proxy/Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/abstractcontractContextUpgradeableisInitializable{
function__Context_init() internalinitializer{
__Context_init_unchained();
}
function__Context_init_unchained() internalinitializer{
}
function_msgSender() internalviewvirtualreturns (addresspayable) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytesmemory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691returnmsg.data;
}
uint256[50] private __gap;
}
Contract Source Code
File 10 of 71: CoreEvent.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;import"../interfaces/ICoreEvent.sol";
import"../interfaces/ILiquidityPool.sol";
import"@openzeppelin/contracts/math/Math.sol";
import"@openzeppelin/contracts/access/Ownable.sol";
import"@openzeppelin/contracts/token/ERC20/ERC20.sol";
import"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import"@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import"@openzeppelin/contracts/utils/EnumerableSet.sol";
import"@openzeppelin/contracts/cryptography/MerkleProof.sol";
contractCoreEventisOwnable, ICoreEvent{
usingSafeMathforuint256;
usingSafeERC20forIERC20;
usingAddressforaddress;
usingEnumerableSetforEnumerableSet.AddressSet;
DurationInfo public durationInfo;
addresspublicimmutable treasuryAddress;
EnumerableSet.AddressSet private supportedTokenAddresses;
// token address -> SupportedTokenDatamapping(address=> SupportedTokenData) public supportedTokens;
// user -> token -> AccountDatamapping(address=>mapping(address=> AccountData)) public accountData;
mapping(address=> RateData) public tokenRates;
WhitelistSettings public whitelistSettings;
boolpublic stage1Locked;
modifierhasEnded() {
require(_hasEnded(), "TOO_EARLY");
_;
}
constructor(address treasury,
SupportedTokenData[] memory tokensToSupport
) public{
treasuryAddress = treasury;
addSupportedTokens(tokensToSupport);
}
functionconfigureWhitelist(WhitelistSettings memory settings) externaloverrideonlyOwner{
whitelistSettings = settings;
emit WhitelistConfigured(settings);
}
functionsetDuration(uint256 _blockDuration) externaloverrideonlyOwner{
require(durationInfo.startingBlock ==0, "ALREADY_STARTED");
durationInfo.startingBlock =block.number;
durationInfo.blockDuration = _blockDuration;
emit DurationSet(durationInfo);
}
functionaddSupportedTokens(SupportedTokenData[] memory tokensToSupport) publicoverrideonlyOwner{
require (tokensToSupport.length>0, "NO_TOKENS");
for (uint256 i =0; i < tokensToSupport.length; i++) {
require(
!supportedTokenAddresses.contains(tokensToSupport[i].token),
"DUPLICATE_TOKEN"
);
require(tokensToSupport[i].token !=address(0), "ZERO_ADDRESS");
require(!tokensToSupport[i].systemFinalized, "FINALIZED_MUST_BE_FALSE");
supportedTokenAddresses.add(tokensToSupport[i].token);
supportedTokens[tokensToSupport[i].token] = tokensToSupport[i];
}
emit SupportedTokensAdded(tokensToSupport);
}
functiondeposit(TokenData[] calldata tokenData, bytes32[] calldata proof) externaloverride{
require(durationInfo.startingBlock >0, "NOT_STARTED");
require(!_hasEnded(), "RATES_LOCKED");
require(tokenData.length>0, "NO_TOKENS");
if (whitelistSettings.enabled) {
require(verifyDepositor(msg.sender, whitelistSettings.root, proof), "PROOF_INVALID");
}
for (uint256 i =0; i < tokenData.length; i++) {
uint256 amount = tokenData[i].amount;
require(amount >0, "0_BALANCE");
address token = tokenData[i].token;
require(supportedTokenAddresses.contains(token), "NOT_SUPPORTED");
IERC20 erc20Token = IERC20(token);
AccountData storage data = accountData[msg.sender][token];
require(
data.depositedBalance.add(amount) <= supportedTokens[token].maxUserLimit,
"OVER_LIMIT"
);
data.depositedBalance = data.depositedBalance.add(amount);
data.token = token;
erc20Token.safeTransferFrom(msg.sender, address(this), amount);
}
emit Deposited(msg.sender, tokenData);
}
functionwithdraw(TokenData[] calldata tokenData) externaloverride{
require(!_hasEnded(), "RATES_LOCKED");
require(tokenData.length>0, "NO_TOKENS");
for (uint256 i =0; i < tokenData.length; i++) {
uint256 amount = tokenData[i].amount;
require(amount >0, "ZERO_BALANCE");
address token = tokenData[i].token;
IERC20 erc20Token = IERC20(token);
AccountData storage data = accountData[msg.sender][token];
require(data.token !=address(0), "ZERO_ADDRESS");
require(amount <= data.depositedBalance, "INSUFFICIENT_FUNDS");
data.depositedBalance = data.depositedBalance.sub(amount);
if (data.depositedBalance ==0) {
delete accountData[msg.sender][token];
}
erc20Token.safeTransfer(msg.sender, amount);
}
emit Withdrawn(msg.sender, tokenData);
}
functionincreaseDuration(uint256 _blockDuration) externaloverrideonlyOwner{
require(durationInfo.startingBlock >0, "NOT_STARTED");
require(_blockDuration > durationInfo.blockDuration, "INCREASE_ONLY");
require(!stage1Locked, "STAGE1_LOCKED");
durationInfo.blockDuration = _blockDuration;
emit DurationIncreased(durationInfo);
}
functionsetRates(RateData[] calldata rates) externaloverrideonlyOwnerhasEnded{
//Rates are settable multiple times, but only until they are finalized.//They are set to finalized by either performing the transferToTreasury//Or, by marking them as no-swap tokens//Users cannot begin their next set of actions before a token finalized.uint256 length = rates.length;
for (uint256 i =0; i < length; i++) {
RateData memory data = rates[i];
require(supportedTokenAddresses.contains(data.token), "UNSUPPORTED_ADDRESS");
require(!supportedTokens[data.token].systemFinalized, "ALREADY_FINALIZED");
if (data.tokeNumerator >0) {
//We are allowing an address(0) pool, it means it was a winning reactor//but there wasn't enough to enable private farming require(data.tokeDenominator >0, "INVALID_TOKE_DENOMINATOR");
require(data.overNumerator >0, "INVALID_OVER_NUMERATOR");
require(data.overDenominator >0, "INVALID_OVER_DENOMINATOR");
tokenRates[data.token] = data;
} else {
delete tokenRates[data.token];
}
}
stage1Locked =true;
emit RatesPublished(rates);
}
functiontransferToTreasury(address[] calldata tokens) externaloverrideonlyOwnerhasEnded{
uint256 length = tokens.length;
TokenData[] memory transfers =new TokenData[](length);
for (uint256 i =0; i < length; i++) {
address token = tokens[i];
require(tokenRates[token].tokeNumerator >0, "NO_SWAP_TOKEN");
require(!supportedTokens[token].systemFinalized, "ALREADY_FINALIZED");
uint256 balance = IERC20(token).balanceOf(address(this));
(uint256 effective, , ) = getRateAdjustedAmounts(balance, token);
transfers[i].token = token;
transfers[i].amount = effective;
supportedTokens[token].systemFinalized =true;
IERC20(token).safeTransfer(treasuryAddress, effective);
}
emit TreasuryTransfer(transfers);
}
functionsetNoSwap(address[] calldata tokens) externaloverrideonlyOwnerhasEnded{
uint256 length = tokens.length;
for (uint256 i =0; i < length; i++) {
address token = tokens[i];
require(supportedTokenAddresses.contains(token), "UNSUPPORTED_ADDRESS");
require(tokenRates[token].tokeNumerator ==0, "ALREADY_SET_TO_SWAP");
require(!supportedTokens[token].systemFinalized, "ALREADY_FINALIZED");
supportedTokens[token].systemFinalized =true;
}
stage1Locked =true;
emit SetNoSwap(tokens);
}
functionfinalize(TokenFarming[] calldata tokens) externaloverridehasEnded{
require(tokens.length>0, "NO_TOKENS");
uint256 length = tokens.length;
FinalizedAccountData[] memory results =new FinalizedAccountData[](length);
for(uint256 i =0; i < length; i++) {
TokenFarming calldata farm = tokens[i];
AccountData storage account = accountData[msg.sender][farm.token];
require(!account.finalized, "ALREADY_FINALIZED");
require(farm.token !=address(0), "ZERO_ADDRESS");
require(supportedTokens[farm.token].systemFinalized, "NOT_SYSTEM_FINALIZED");
require(account.depositedBalance >0, "INSUFFICIENT_FUNDS");
RateData storage rate = tokenRates[farm.token];
uint256 amtToTransfer =0;
if (rate.tokeNumerator >0) {
//We have set a rate, which means its a winning reactor//which means only the ineffective amount, the amount//not spent on TOKE, can leave the contract.//Leaving to either the farm or back to the user//In the event there is no farming, an oversubscription rate of 1/1 //will be provided for the token. That will ensure the ineffective//amount is 0 and caught by the below require() as only assets with //an oversubscription can be moved
(, uint256 ineffectiveAmt, ) = getRateAdjustedAmounts(account.depositedBalance, farm.token);
amtToTransfer = ineffectiveAmt;
} else {
amtToTransfer = account.depositedBalance;
}
require(amtToTransfer >0, "NOTHING_TO_MOVE");
account.finalized =true;
if (farm.sendToFarming) {
require(rate.pool !=address(0), "NO_FARMING");
uint256 currentAllowance = IERC20(farm.token).allowance(address(this), rate.pool);
if (currentAllowance < amtToTransfer) {
IERC20(farm.token).safeIncreaseAllowance(rate.pool, amtToTransfer.sub(currentAllowance));
}
ILiquidityPool(rate.pool).depositFor(msg.sender, amtToTransfer);
results[i] = FinalizedAccountData({
token: farm.token,
transferredToFarm: amtToTransfer,
refunded: 0
});
} else {
IERC20(farm.token).safeTransfer(msg.sender, amtToTransfer);
results[i] = FinalizedAccountData({
token: farm.token,
transferredToFarm: 0,
refunded: amtToTransfer
});
}
}
emit AssetsFinalized(msg.sender, results);
}
functiongetRateAdjustedAmounts(uint256 balance, address token) publicoverrideviewreturns (uint256 effectiveAmt, uint256 ineffectiveAmt, uint256 actualReceived) {
RateData memory rateInfo = tokenRates[token];
uint256 effectiveTokenBalance =
balance.mul(rateInfo.overNumerator).div(rateInfo.overDenominator);
uint256 ineffectiveTokenBalance =
balance.mul(rateInfo.overDenominator.sub(rateInfo.overNumerator))
.div(rateInfo.overDenominator);
uint256 actual =
effectiveTokenBalance.mul(rateInfo.tokeDenominator).div(rateInfo.tokeNumerator);
return (effectiveTokenBalance, ineffectiveTokenBalance, actual);
}
functiongetRates() externaloverrideviewreturns (RateData[] memory rates) {
uint256 length = supportedTokenAddresses.length();
rates =new RateData[](length);
for (uint256 i =0; i < length; i++) {
address token = supportedTokenAddresses.at(i);
rates[i] = tokenRates[token];
}
}
functiongetAccountData(address account) externalviewoverridereturns (AccountData[] memory data) {
uint256 length = supportedTokenAddresses.length();
data =new AccountData[](length);
for(uint256 i =0; i < length; i++) {
address token = supportedTokenAddresses.at(i);
data[i] = accountData[account][token];
data[i].token = token;
}
}
functiongetSupportedTokens() externalviewoverridereturns (SupportedTokenData[] memory supportedTokensArray) {
uint256 supportedTokensLength = supportedTokenAddresses.length();
supportedTokensArray =new SupportedTokenData[](supportedTokensLength);
for (uint256 i =0; i < supportedTokensLength; i++) {
supportedTokensArray[i] = supportedTokens[supportedTokenAddresses.at(i)];
}
return supportedTokensArray;
}
function_hasEnded() privateviewreturns (bool) {
return durationInfo.startingBlock >0&&block.number>= durationInfo.blockDuration + durationInfo.startingBlock;
}
functionverifyDepositor(address participant, bytes32 root, bytes32[] memory proof) internalpurereturns (bool) {
bytes32 leaf =keccak256((abi.encodePacked((participant))));
return MerkleProof.verify(proof, root, leaf);
}
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/libraryECDSA{
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/functionrecover(bytes32 hash, bytesmemory signature) internalpurereturns (address) {
// Check the signature lengthif (signature.length!=65) {
revert("ECDSA: invalid signature length");
}
// Divide the signature in r, s and v variablesbytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them// currently is to use assembly.// solhint-disable-next-line no-inline-assemblyassembly {
r :=mload(add(signature, 0x20))
s :=mload(add(signature, 0x40))
v :=byte(0, mload(add(signature, 0x60)))
}
return recover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,
* `r` and `s` signature fields separately.
*/functionrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internalpurereturns (address) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most// signatures from current libraries generate a unique signature with an s-value in the lower half order.//// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept// these malleable signatures as well.require(uint256(s) <=0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
require(v ==27|| v ==28, "ECDSA: invalid signature 'v' value");
// If the signature is valid (and not malleable), return the signer addressaddress signer =ecrecover(hash, v, r, s);
require(signer !=address(0), "ECDSA: invalid signature");
return signer;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* replicates the behavior of the
* https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
* JSON-RPC method.
*
* See {recover}.
*/functiontoEthSignedMessageHash(bytes32 hash) internalpurereturns (bytes32) {
// 32 is the length in bytes of hash,// enforced by the type signature abovereturnkeccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}
Contract Source Code
File 13 of 71: ERC20.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../../utils/Context.sol";
import"./IERC20.sol";
import"../../math/SafeMath.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/contractERC20isContext, IERC20{
usingSafeMathforuint256;
mapping (address=>uint256) private _balances;
mapping (address=>mapping (address=>uint256)) private _allowances;
uint256private _totalSupply;
stringprivate _name;
stringprivate _symbol;
uint8private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/constructor (stringmemory name_, stringmemory symbol_) public{
_name = name_;
_symbol = symbol_;
_decimals =18;
}
/**
* @dev Returns the name of the token.
*/functionname() publicviewvirtualreturns (stringmemory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/functionsymbol() publicviewvirtualreturns (stringmemory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/functiondecimals() publicviewvirtualreturns (uint8) {
return _decimals;
}
/**
* @dev See {IERC20-totalSupply}.
*/functiontotalSupply() publicviewvirtualoverridereturns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/functionbalanceOf(address account) publicviewvirtualoverridereturns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/functiontransfer(address recipient, uint256 amount) publicvirtualoverridereturns (bool) {
_transfer(_msgSender(), recipient, amount);
returntrue;
}
/**
* @dev See {IERC20-allowance}.
*/functionallowance(address owner, address spender) publicviewvirtualoverridereturns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionapprove(address spender, uint256 amount) publicvirtualoverridereturns (bool) {
_approve(_msgSender(), spender, amount);
returntrue;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/functiontransferFrom(address sender, address recipient, uint256 amount) publicvirtualoverridereturns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
returntrue;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionincreaseAllowance(address spender, uint256 addedValue) publicvirtualreturns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
returntrue;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/functiondecreaseAllowance(address spender, uint256 subtractedValue) publicvirtualreturns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
returntrue;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/function_transfer(address sender, address recipient, uint256 amount) internalvirtual{
require(sender !=address(0), "ERC20: transfer from the zero address");
require(recipient !=address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/function_mint(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/function_burn(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/function_approve(address owner, address spender, uint256 amount) internalvirtual{
require(owner !=address(0), "ERC20: approve from the zero address");
require(spender !=address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/function_setupDecimals(uint8 decimals_) internalvirtual{
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/function_beforeTokenTransfer(addressfrom, address to, uint256 amount) internalvirtual{ }
}
Contract Source Code
File 14 of 71: ERC20Burnable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../../utils/Context.sol";
import"./ERC20.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/abstractcontractERC20BurnableisContext, ERC20{
usingSafeMathforuint256;
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/functionburn(uint256 amount) publicvirtual{
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/functionburnFrom(address account, uint256 amount) publicvirtual{
uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance");
_approve(account, _msgSender(), decreasedAllowance);
_burn(account, amount);
}
}
Contract Source Code
File 15 of 71: ERC20Pausable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./ERC20.sol";
import"../../utils/Pausable.sol";
/**
* @dev ERC20 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*/abstractcontractERC20PausableisERC20, Pausable{
/**
* @dev See {ERC20-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/function_beforeTokenTransfer(addressfrom, address to, uint256 amount) internalvirtualoverride{
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC20Pausable: token transfer while paused");
}
}
Contract Source Code
File 16 of 71: ERC20PresetMinterPauser.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../access/AccessControl.sol";
import"../utils/Context.sol";
import"../token/ERC20/ERC20.sol";
import"../token/ERC20/ERC20Burnable.sol";
import"../token/ERC20/ERC20Pausable.sol";
/**
* @dev {ERC20} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/contractERC20PresetMinterPauserisContext, AccessControl, ERC20Burnable, ERC20Pausable{
bytes32publicconstant MINTER_ROLE =keccak256("MINTER_ROLE");
bytes32publicconstant PAUSER_ROLE =keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC20-constructor}.
*/constructor(stringmemory name, stringmemory symbol) publicERC20(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`.
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/functionmint(address to, uint256 amount) publicvirtual{
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
_mint(to, amount);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/functionpause() publicvirtual{
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/functionunpause() publicvirtual{
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause");
_unpause();
}
function_beforeTokenTransfer(addressfrom, address to, uint256 amount) internalvirtualoverride(ERC20, ERC20Pausable) {
super._beforeTokenTransfer(from, to, amount);
}
}
Contract Source Code
File 17 of 71: ERC20Upgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../../utils/ContextUpgradeable.sol";
import"./IERC20Upgradeable.sol";
import"../../math/SafeMathUpgradeable.sol";
import"../../proxy/Initializable.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/contractERC20UpgradeableisInitializable, ContextUpgradeable, IERC20Upgradeable{
usingSafeMathUpgradeableforuint256;
mapping (address=>uint256) private _balances;
mapping (address=>mapping (address=>uint256)) private _allowances;
uint256private _totalSupply;
stringprivate _name;
stringprivate _symbol;
uint8private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/function__ERC20_init(stringmemory name_, stringmemory symbol_) internalinitializer{
__Context_init_unchained();
__ERC20_init_unchained(name_, symbol_);
}
function__ERC20_init_unchained(stringmemory name_, stringmemory symbol_) internalinitializer{
_name = name_;
_symbol = symbol_;
_decimals =18;
}
/**
* @dev Returns the name of the token.
*/functionname() publicviewvirtualreturns (stringmemory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/functionsymbol() publicviewvirtualreturns (stringmemory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/functiondecimals() publicviewvirtualreturns (uint8) {
return _decimals;
}
/**
* @dev See {IERC20-totalSupply}.
*/functiontotalSupply() publicviewvirtualoverridereturns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/functionbalanceOf(address account) publicviewvirtualoverridereturns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/functiontransfer(address recipient, uint256 amount) publicvirtualoverridereturns (bool) {
_transfer(_msgSender(), recipient, amount);
returntrue;
}
/**
* @dev See {IERC20-allowance}.
*/functionallowance(address owner, address spender) publicviewvirtualoverridereturns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionapprove(address spender, uint256 amount) publicvirtualoverridereturns (bool) {
_approve(_msgSender(), spender, amount);
returntrue;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/functiontransferFrom(address sender, address recipient, uint256 amount) publicvirtualoverridereturns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
returntrue;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionincreaseAllowance(address spender, uint256 addedValue) publicvirtualreturns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
returntrue;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/functiondecreaseAllowance(address spender, uint256 subtractedValue) publicvirtualreturns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
returntrue;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/function_transfer(address sender, address recipient, uint256 amount) internalvirtual{
require(sender !=address(0), "ERC20: transfer from the zero address");
require(recipient !=address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/function_mint(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/function_burn(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/function_approve(address owner, address spender, uint256 amount) internalvirtual{
require(owner !=address(0), "ERC20: approve from the zero address");
require(spender !=address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/function_setupDecimals(uint8 decimals_) internalvirtual{
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/function_beforeTokenTransfer(addressfrom, address to, uint256 amount) internalvirtual{ }
uint256[44] private __gap;
}
Contract Source Code
File 18 of 71: EnumerableSet.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/libraryEnumerableSet{
// To implement this library for multiple types with as little code// repetition as possible, we write it in terms of a generic Set type with// bytes32 values.// The Set implementation uses private functions, and user-facing// implementations (such as AddressSet) are just wrappers around the// underlying Set.// This means that we can only create new EnumerableSets for types that fit// in bytes32.structSet {
// Storage of set valuesbytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0// means a value is not in the set.mapping (bytes32=>uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/function_add(Set storage set, bytes32 value) privatereturns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
returntrue;
} else {
returnfalse;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/function_remove(Set storage set, bytes32 value) privatereturns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slotuint256 valueIndex = set._indexes[value];
if (valueIndex !=0) { // Equivalent to contains(set, value)// To delete an element from the _values array in O(1), we swap the element to delete with the last one in// the array, and then remove the last element (sometimes called as 'swap and pop').// This modifies the order of the array, as noted in {at}.uint256 toDeleteIndex = valueIndex -1;
uint256 lastIndex = set._values.length-1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex +1; // All indexes are 1-based// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slotdelete set._indexes[value];
returntrue;
} else {
returnfalse;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/function_contains(Set storage set, bytes32 value) privateviewreturns (bool) {
return set._indexes[value] !=0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/function_length(Set storage set) privateviewreturns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/function_at(Set storage set, uint256 index) privateviewreturns (bytes32) {
require(set._values.length> index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32SetstructBytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(Bytes32Set storage set, bytes32 value) internalreturns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(Bytes32Set storage set, bytes32 value) internalreturns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(Bytes32Set storage set, bytes32 value) internalviewreturns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/functionlength(Bytes32Set storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(Bytes32Set storage set, uint256 index) internalviewreturns (bytes32) {
return _at(set._inner, index);
}
// AddressSetstructAddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(AddressSet storage set, address value) internalreturns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(AddressSet storage set, address value) internalreturns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(AddressSet storage set, address value) internalviewreturns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/functionlength(AddressSet storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(AddressSet storage set, uint256 index) internalviewreturns (address) {
returnaddress(uint160(uint256(_at(set._inner, index))));
}
// UintSetstructUintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(UintSet storage set, uint256 value) internalreturns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(UintSet storage set, uint256 value) internalreturns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(UintSet storage set, uint256 value) internalviewreturns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/functionlength(UintSet storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(UintSet storage set, uint256 index) internalviewreturns (uint256) {
returnuint256(_at(set._inner, index));
}
}
Contract Source Code
File 19 of 71: EnumerableSetUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/libraryEnumerableSetUpgradeable{
// To implement this library for multiple types with as little code// repetition as possible, we write it in terms of a generic Set type with// bytes32 values.// The Set implementation uses private functions, and user-facing// implementations (such as AddressSet) are just wrappers around the// underlying Set.// This means that we can only create new EnumerableSets for types that fit// in bytes32.structSet {
// Storage of set valuesbytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0// means a value is not in the set.mapping (bytes32=>uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/function_add(Set storage set, bytes32 value) privatereturns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
returntrue;
} else {
returnfalse;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/function_remove(Set storage set, bytes32 value) privatereturns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slotuint256 valueIndex = set._indexes[value];
if (valueIndex !=0) { // Equivalent to contains(set, value)// To delete an element from the _values array in O(1), we swap the element to delete with the last one in// the array, and then remove the last element (sometimes called as 'swap and pop').// This modifies the order of the array, as noted in {at}.uint256 toDeleteIndex = valueIndex -1;
uint256 lastIndex = set._values.length-1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex +1; // All indexes are 1-based// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slotdelete set._indexes[value];
returntrue;
} else {
returnfalse;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/function_contains(Set storage set, bytes32 value) privateviewreturns (bool) {
return set._indexes[value] !=0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/function_length(Set storage set) privateviewreturns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/function_at(Set storage set, uint256 index) privateviewreturns (bytes32) {
require(set._values.length> index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32SetstructBytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(Bytes32Set storage set, bytes32 value) internalreturns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(Bytes32Set storage set, bytes32 value) internalreturns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(Bytes32Set storage set, bytes32 value) internalviewreturns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/functionlength(Bytes32Set storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(Bytes32Set storage set, uint256 index) internalviewreturns (bytes32) {
return _at(set._inner, index);
}
// AddressSetstructAddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(AddressSet storage set, address value) internalreturns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(AddressSet storage set, address value) internalreturns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(AddressSet storage set, address value) internalviewreturns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/functionlength(AddressSet storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(AddressSet storage set, uint256 index) internalviewreturns (address) {
returnaddress(uint160(uint256(_at(set._inner, index))));
}
// UintSetstructUintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(UintSet storage set, uint256 value) internalreturns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(UintSet storage set, uint256 value) internalreturns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(UintSet storage set, uint256 value) internalviewreturns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/functionlength(UintSet storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(UintSet storage set, uint256 index) internalviewreturns (uint256) {
returnuint256(_at(set._inner, index));
}
}
Contract Source Code
File 20 of 71: EthPool.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;import"../interfaces/ILiquidityEthPool.sol";
import"../interfaces/IManager.sol";
import"../interfaces/IWETH.sol";
import"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import {AddressUpgradeableasAddress} from"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import {MathUpgradeableasMath} from"@openzeppelin/contracts-upgradeable/math/MathUpgradeable.sol";
import {SafeMathUpgradeableasSafeMath} from"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import {OwnableUpgradeableasOwnable} from"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {ERC20UpgradeableasERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {IERC20UpgradeableasIERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20UpgradeableasSafeERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol";
import {PausableUpgradeableasPausable} from"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
contractEthPoolisILiquidityEthPool, Initializable, ERC20, Ownable, Pausable{
usingSafeMathforuint256;
usingSafeERC20forIERC20;
usingAddressforaddress;
usingAddressforaddresspayable;
/// @dev TODO: Hardcode addresses, make immuatable, remove from initializer
IWETH publicoverride weth;
IManager public manager;
// implied: deployableLiquidity = underlyer.balanceOf(this) - withheldLiquidityuint256publicoverride withheldLiquidity;
// fAsset holder -> WithdrawalInfomapping(address=> WithdrawalInfo) publicoverride requestedWithdrawals;
/// @dev necessary to receive ETH// solhint-disable-next-line no-empty-blocksreceive() externalpayable{}
functioninitialize(
IWETH _weth,
IManager _manager,
stringmemory _name,
stringmemory _symbol
) publicinitializer{
require(address(_weth) !=address(0), "ZERO_ADDRESS");
require(address(_manager) !=address(0), "ZERO_ADDRESS");
__Context_init_unchained();
__Ownable_init_unchained();
__Pausable_init_unchained();
__ERC20_init_unchained(_name, _symbol);
weth = _weth;
manager = _manager;
withheldLiquidity =0;
}
functiondeposit(uint256 amount) externalpayableoverridewhenNotPaused{
_deposit(msg.sender, msg.sender, amount, msg.value);
}
functiondepositFor(address account, uint256 amount) externalpayableoverridewhenNotPaused{
_deposit(msg.sender, account, amount, msg.value);
}
functionunderlyer() externalviewoverridereturns (address) {
returnaddress(weth);
}
/// @dev References the WithdrawalInfo for how much the user is permitted to withdraw/// @dev No withdrawal permitted unless currentCycle >= minCycle/// @dev Decrements withheldLiquidity by the withdrawn amountfunctionwithdraw(uint256 requestedAmount, bool asEth) externaloverridewhenNotPaused{
require(
requestedAmount <= requestedWithdrawals[msg.sender].amount,
"WITHDRAW_INSUFFICIENT_BALANCE"
);
require(requestedAmount >0, "NO_WITHDRAWAL");
require(weth.balanceOf(address(this)) >= requestedAmount, "INSUFFICIENT_POOL_BALANCE");
require(
requestedWithdrawals[msg.sender].minCycle <= manager.getCurrentCycleIndex(),
"INVALID_CYCLE"
);
requestedWithdrawals[msg.sender].amount = requestedWithdrawals[msg.sender].amount.sub(
requestedAmount
);
if (requestedWithdrawals[msg.sender].amount ==0) {
delete requestedWithdrawals[msg.sender];
}
withheldLiquidity = withheldLiquidity.sub(requestedAmount);
_burn(msg.sender, requestedAmount);
if (asEth) {
weth.withdraw(requestedAmount);
msg.sender.sendValue(requestedAmount);
} else {
IERC20(weth).safeTransfer(msg.sender, requestedAmount);
}
}
/// @dev Adjusts the withheldLiquidity as necessary/// @dev Updates the WithdrawalInfo for when a user can withdraw and for what requested amountfunctionrequestWithdrawal(uint256 amount) externaloverride{
require(amount >0, "INVALID_AMOUNT");
require(amount <= balanceOf(msg.sender), "INSUFFICIENT_BALANCE");
//adjust withheld liquidity by removing the original withheld amount and adding the new amount
withheldLiquidity = withheldLiquidity.sub(requestedWithdrawals[msg.sender].amount).add(
amount
);
requestedWithdrawals[msg.sender].amount = amount;
if (manager.getRolloverStatus()) {
requestedWithdrawals[msg.sender].minCycle = manager.getCurrentCycleIndex().add(2);
} else {
requestedWithdrawals[msg.sender].minCycle = manager.getCurrentCycleIndex().add(1);
}
}
functionpreTransferAdjustWithheldLiquidity(address sender, uint256 amount) internal{
if (requestedWithdrawals[sender].amount >0) {
//reduce requested withdraw amount by transferred amount;uint256 newRequestedWithdrawl = requestedWithdrawals[sender].amount.sub(
Math.min(amount, requestedWithdrawals[sender].amount)
);
//subtract from global withheld liquidity (reduce) by removing the delta of (requestedAmount - newRequestedAmount)
withheldLiquidity = withheldLiquidity.sub(
requestedWithdrawals[msg.sender].amount.sub(newRequestedWithdrawl)
);
//update the requested withdraw for user
requestedWithdrawals[msg.sender].amount = newRequestedWithdrawl;
//if the withdraw request is 0, empty it outif (requestedWithdrawals[msg.sender].amount ==0) {
delete requestedWithdrawals[msg.sender];
}
}
}
functionapproveManager(uint256 amount) publicoverrideonlyOwner{
uint256 currentAllowance = IERC20(weth).allowance(address(this), address(manager));
if (currentAllowance < amount) {
uint256 delta = amount.sub(currentAllowance);
IERC20(weth).safeIncreaseAllowance(address(manager), delta);
} else {
uint256 delta = currentAllowance.sub(amount);
IERC20(weth).safeDecreaseAllowance(address(manager), delta);
}
}
/// @dev Adjust withheldLiquidity and requestedWithdrawal if sender does not have sufficient unlocked balance for the transferfunctiontransfer(address recipient, uint256 amount) publicoverridereturns (bool) {
preTransferAdjustWithheldLiquidity(msg.sender, amount);
returnsuper.transfer(recipient, amount);
}
/// @dev Adjust withheldLiquidity and requestedWithdrawal if sender does not have sufficient unlocked balance for the transferfunctiontransferFrom(address sender,
address recipient,
uint256 amount
) publicoverridereturns (bool) {
preTransferAdjustWithheldLiquidity(sender, amount);
returnsuper.transferFrom(sender, recipient, amount);
}
functionpause() externaloverrideonlyOwner{
_pause();
}
functionunpause() externaloverrideonlyOwner{
_unpause();
}
function_deposit(address fromAccount,
address toAccount,
uint256 amount,
uint256 msgValue
) internal{
require(amount >0, "INVALID_AMOUNT");
require(toAccount !=address(0), "INVALID_ADDRESS");
_mint(toAccount, amount);
if (msgValue >0) {
require(msgValue == amount, "AMT_VALUE_MISMATCH");
weth.deposit{value: amount}();
} else {
IERC20(weth).safeTransferFrom(fromAccount, address(this), amount);
}
}
}
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;interfaceICoreEvent{
structSupportedTokenData {
address token;
uint256 maxUserLimit;
bool systemFinalized; // Whether or not the system is done setting rates, doing transfers, for this token
}
structDurationInfo {
uint256 startingBlock;
uint256 blockDuration; // Block duration of the deposit/withdraw stage
}
structRateData {
address token;
uint256 tokeNumerator;
uint256 tokeDenominator;
uint256 overNumerator;
uint256 overDenominator;
address pool;
}
structTokenData {
address token;
uint256 amount;
}
structAccountData {
address token; // Address of the allowed token deposited uint256 depositedBalance;
bool finalized; // Has the user either taken their refund or sent to farming. Will not be set on swapped but undersubscribed tokens.
}
structFinalizedAccountData {
address token;
uint256 transferredToFarm;
uint256 refunded;
}
structTokenFarming {
address token; // address of the allowed token deposited bool sendToFarming; // Refund is default
}
structWhitelistSettings {
bool enabled;
bytes32 root;
}
eventSupportedTokensAdded(SupportedTokenData[] tokenData);
eventTreasurySet(address treasury);
eventDurationSet(DurationInfo duration);
eventDurationIncreased(DurationInfo duration);
eventDeposited(address depositor, TokenData[] tokenInfo);
eventWithdrawn(address withdrawer, TokenData[] tokenInfo);
eventRatesPublished(RateData[] ratesData);
eventAssetsFinalized(address user, FinalizedAccountData[] data);
eventTreasuryTransfer(TokenData[] tokens);
eventWhitelistConfigured(WhitelistSettings settings);
eventSetNoSwap(address[] tokens);
//==========================================// Initial setup operations//========================================== /// @notice Enable or disable the whitelist/// @param settings The root to use and whether to check the whitelist at allfunctionconfigureWhitelist(WhitelistSettings memory settings) external;
/// @notice defines the length in blocks the round will run for/// @notice round is started via this call and it is only callable one time/// @param blockDuration Duration in blocks the deposit/withdraw portion will run forfunctionsetDuration(uint256 blockDuration) external;
/// @notice adds tokens to support/// @param tokensToSupport an array of supported token structsfunctionaddSupportedTokens(SupportedTokenData[] memory tokensToSupport) external;
//==========================================// Stage 1 timeframe operations//==========================================/// @notice deposits tokens into the round contract/// @param tokenData an array of token structs/// @param proof Merkle proof for the user. Only required if whitelistSettings.enabledfunctiondeposit(TokenData[] calldata tokenData, bytes32[] calldata proof) external;
/// @notice withdraws tokens from the round contract/// @param tokenData an array of token structsfunctionwithdraw(TokenData[] calldata tokenData) external;
/// @notice extends the deposit/withdraw stage/// @notice Only extendable if no tokens have been finalized and no rates set/// @param blockDuration Duration in blocks the deposit/withdraw portion will run for. Must be greater than originalfunctionincreaseDuration(uint256 blockDuration) external;
//==========================================// Stage 1 -> 2 transition operations//==========================================/// @notice once the expected duration has passed, publish the Toke and over subscription rates/// @notice tokens which do not have a published rate will have their users forced to withdraw all funds /// @dev pass a tokeNumerator of 0 to delete a set rate/// @dev Cannot be called for a token once transferToTreasury/setNoSwap has been called for that tokenfunctionsetRates(RateData[] calldata rates) external;
/// @notice Allows the owner to transfer the effective balance of a token based on the set rate to the treasury/// @dev only callable by owner and if rates have been set/// @dev is only callable one time for a tokenfunctiontransferToTreasury(address[] calldata tokens) external;
/// @notice Marks a token as finalized but not swapping/// @dev complement to transferToTreasury which is for tokens that will be swapped, this one for ones that won'tfunctionsetNoSwap(address[] calldata tokens) external;
//========================================== // Stage 2 operations//==========================================/// @notice Once rates have been published, and the token finalized via transferToTreasury/setNoSwap, either refunds or sends to private farming/// @param tokens an array of tokens and whether to send them to private farming. False on farming will send back to user.functionfinalize(TokenFarming[] calldata tokens) external;
//==========================================// View operations//==========================================/// @notice Breaks down the balance according to the published rates/// @dev only callable after rates have been setfunctiongetRateAdjustedAmounts(uint256 balance, address token) externalviewreturns (uint256 effectiveAmt, uint256 ineffectiveAmt, uint256 actualReceived);
/// @notice return the published rates for the tokens /// @return rates an array of rates for the provided tokensfunctiongetRates() externalviewreturns (RateData[] memory rates);
/// @notice returns a list of AccountData for a provided account/// @param account the address of the account/// @return data an array of AccountData denoting what the status is for each of the tokens deposited (if any)functiongetAccountData(address account) externalviewreturns (AccountData[] calldata data);
/// @notice get all tokens currently supported by the contract/// @return supportedTokensArray an array of supported token structsfunctiongetSupportedTokens() externalviewreturns (SupportedTokenData[] memory supportedTokensArray);
}
Contract Source Code
File 23 of 71: IDefiRound.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;interfaceIDefiRound{
enumSTAGES {STAGE_1, STAGE_2, STAGE_3}
structAccountData {
address token; // address of the allowed token depositeduint256 initialDeposit; // initial amount deposited of the tokenuint256 currentBalance; // current balance of the token that can be used to claim TOKE
}
structAccountDataDetails {
address token; // address of the allowed token depositeduint256 initialDeposit; // initial amount deposited of the tokenuint256 currentBalance; // current balance of the token that can be used to claim TOKEuint256 effectiveAmt; //Amount deposited that will be used towards TOKEuint256 ineffectiveAmt; //Amount deposited that will be either refunded or go to farminguint256 actualTokeReceived; //Amount of TOKE that will be received
}
structTokenData {
address token;
uint256 amount;
}
structSupportedTokenData {
address token;
address oracle;
address genesis;
uint256 maxLimit;
}
structRateData {
address token;
uint256 numerator;
uint256 denominator;
}
structOversubscriptionRate {
uint256 overNumerator;
uint256 overDenominator;
}
eventDeposited(address depositor, TokenData tokenInfo);
eventWithdrawn(address withdrawer, TokenData tokenInfo, bool asETH);
eventSupportedTokensAdded(SupportedTokenData[] tokenData);
eventRatesPublished(RateData[] ratesData);
eventGenesisTransfer(address user, uint256 amountTransferred);
eventAssetsFinalized(address claimer, address token, uint256 assetsMoved);
eventWhitelistConfigured(WhitelistSettings settings);
eventTreasuryTransfer(TokenData[] tokens);
structTokenValues {
uint256 effectiveTokenValue;
uint256 ineffectiveTokenValue;
}
structWhitelistSettings {
bool enabled;
bytes32 root;
}
/// @notice Enable or disable the whitelist/// @param settings The root to use and whether to check the whitelist at allfunctionconfigureWhitelist(WhitelistSettings calldata settings) external;
/// @notice returns the current stage the contract is in/// @return stage the current stage the round contract is infunctioncurrentStage() externalreturns (STAGES stage);
/// @notice deposits tokens into the round contract/// @param tokenData an array of token structsfunctiondeposit(TokenData calldata tokenData, bytes32[] memory proof) externalpayable;
/// @notice total value held in the entire contract amongst all the assets/// @return value the value of all assets heldfunctiontotalValue() externalviewreturns (uint256 value);
/// @notice Current Max Total ValuefunctiongetMaxTotalValue() externalviewreturns (uint256 value);
/// @notice returns the address of the treasury, when users claim this is where funds that are <= maxClaimableValue go/// @return treasuryAddress address of the treasuryfunctiontreasury() externalreturns (address treasuryAddress);
/// @notice the total supply held for a given token/// @param token the token to get the supply for/// @return amount the total supply for a given tokenfunctiontotalSupply(address token) externalreturns (uint256 amount);
/// @notice withdraws tokens from the round contract. only callable when round 2 starts/// @param tokenData an array of token structs/// @param asEth flag to determine if provided WETH, that it should be withdrawn as ETHfunctionwithdraw(TokenData calldata tokenData, bool asEth) external;
// /// @notice adds tokens to support// /// @param tokensToSupport an array of supported token structsfunctionaddSupportedTokens(SupportedTokenData[] calldata tokensToSupport) external;
// /// @notice returns which tokens can be deposited// /// @return tokens tokens that are supported for depositfunctiongetSupportedTokens() externalviewreturns (address[] calldata tokens);
/// @notice the oracle that will be used to denote how much the amounts deposited are worth in USD/// @param tokens an array of tokens/// @return oracleAddresses the an array of oracles corresponding to supported tokensfunctiongetTokenOracles(address[] calldata tokens)
externalviewreturns (address[] calldata oracleAddresses);
/// @notice publishes rates for the tokens. Rates are always relative to 1 TOKE. Can only be called once within Stage 1// prices can be published at any time/// @param ratesData an array of rate info structsfunctionpublishRates(
RateData[] calldata ratesData,
OversubscriptionRate memory overSubRate,
uint256 lastLookDuration
) external;
/// @notice return the published rates for the tokens/// @param tokens an array of tokens to get rates for/// @return rates an array of rates for the provided tokensfunctiongetRates(address[] calldata tokens) externalviewreturns (RateData[] calldata rates);
/// @notice determines the account value in USD amongst all the assets the user is invovled in/// @param account the account to look up/// @return value the value of the account in USDfunctionaccountBalance(address account) externalviewreturns (uint256 value);
/// @notice Moves excess assets to private farming or refunds them/// @dev uses the publishedRates, selected tokens, and amounts to determine what amount of TOKE is claimed/// @param depositToGenesis applies only if oversubscribedMultiplier < 1;/// when true oversubscribed amount will deposit to genesis, else oversubscribed amount is sent back to userfunctionfinalizeAssets(bool depositToGenesis) external;
//// @notice returns what gensis pool a supported token is mapped to/// @param tokens array of addresses of supported tokens/// @return genesisAddresses array of genesis pools corresponding to supported tokensfunctiongetGenesisPools(address[] calldata tokens)
externalviewreturns (address[] memory genesisAddresses);
/// @notice returns a list of AccountData for a provided account/// @param account the address of the account/// @return data an array of AccountData denoting what the status is for each of the tokens deposited (if any)functiongetAccountData(address account)
externalviewreturns (AccountDataDetails[] calldata data);
/// @notice Allows the owner to transfer all swapped assets to the treasury/// @dev only callable by owner and if last look period is completefunctiontransferToTreasury() external;
/// @notice Given a balance, calculates how the the amount will be allocated between TOKE and Farming/// @dev Only allowed at stage 3/// @param balance balance to divy up/// @param token token to pull the rates forfunctiongetRateAdjustedAmounts(uint256 balance, address token)
externalviewreturns (uint256,
uint256,
uint256);
}
Contract Source Code
File 24 of 71: IERC20.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender, address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
Contract Source Code
File 25 of 71: IERC20TokenV06.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;interfaceIERC20TokenV06{
// solhint-disable no-simple-event-func-nameeventTransfer(addressindexedfrom,
addressindexed to,
uint256 value
);
eventApproval(addressindexed owner,
addressindexed spender,
uint256 value
);
/// @dev send `value` token to `to` from `msg.sender`/// @param to The address of the recipient/// @param value The amount of token to be transferred/// @return True if transfer was successfulfunctiontransfer(address to, uint256 value)
externalreturns (bool);
/// @dev send `value` token to `to` from `from` on the condition it is approved by `from`/// @param from The address of the sender/// @param to The address of the recipient/// @param value The amount of token to be transferred/// @return True if transfer was successfulfunctiontransferFrom(addressfrom,
address to,
uint256 value
)
externalreturns (bool);
/// @dev `msg.sender` approves `spender` to spend `value` tokens/// @param spender The address of the account able to transfer the tokens/// @param value The amount of wei to be approved for transfer/// @return Always true if the call has enough gas to complete executionfunctionapprove(address spender, uint256 value)
externalreturns (bool);
/// @dev Query total supply of token/// @return Total supply of tokenfunctiontotalSupply()
externalviewreturns (uint256);
/// @dev Get the balance of `owner`./// @param owner The address from which the balance will be retrieved/// @return Balance of ownerfunctionbalanceOf(address owner)
externalviewreturns (uint256);
/// @dev Get the allowance for `spender` to spend from `owner`./// @param owner The address of the account owning tokens/// @param spender The address of the account able to transfer the tokens/// @return Amount of remaining tokens allowed to spentfunctionallowance(address owner, address spender)
externalviewreturns (uint256);
/// @dev Get the number of decimals this token has.functiondecimals()
externalviewreturns (uint8);
}
Contract Source Code
File 26 of 71: IERC20Upgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20Upgradeable{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender, address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
Contract Source Code
File 27 of 71: ILiquidityEthPool.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;import"../interfaces/IWETH.sol";
import"../interfaces/IManager.sol";
/// @title Interface for Pool/// @notice Allows users to deposit ERC-20 tokens to be deployed to market makers./// @notice Mints 1:1 fToken on deposit, represeting an IOU for the undelrying token that is freely transferable./// @notice Holders of fTokens earn rewards based on duration their tokens were deployed and the demand for that asset./// @notice Holders of fTokens can redeem for underlying asset after issuing requestWithdrawal and waiting for the next cycle.interfaceILiquidityEthPool{
structWithdrawalInfo {
uint256 minCycle;
uint256 amount;
}
/// @notice Transfers amount of underlying token from user to this pool and mints fToken to the msg.sender./// @notice Depositor must have previously granted transfer approval to the pool via underlying token contract./// @notice Liquidity deposited is deployed on the next cycle - unless a withdrawal request is submitted, in which case the liquidity will be withheld.functiondeposit(uint256 amount) externalpayable;
/// @notice Transfers amount of underlying token from user to this pool and mints fToken to the account./// @notice Depositor must have previously granted transfer approval to the pool via underlying token contract./// @notice Liquidity deposited is deployed on the next cycle - unless a withdrawal request is submitted, in which case the liquidity will be withheld.functiondepositFor(address account, uint256 amount) externalpayable;
/// @notice Requests that the manager prepare funds for withdrawal next cycle/// @notice Invoking this function when sender already has a currently pending request will overwrite that requested amount and reset the cycle timer/// @param amount Amount of fTokens requested to be redeemedfunctionrequestWithdrawal(uint256 amount) external;
functionapproveManager(uint256 amount) external;
/// @notice Sender must first invoke requestWithdrawal in a previous cycle/// @notice This function will burn the fAsset and transfers underlying asset back to sender/// @notice Will execute a partial withdrawal if either available liquidity or previously requested amount is insufficient/// @param amount Amount of fTokens to redeem, value can be in excess of available tokens, operation will be reduced to maximum permissiblefunctionwithdraw(uint256 amount, bool asEth) external;
/// @return Reference to the underlying ERC-20 contractfunctionweth() externalviewreturns (IWETH);
/// @return Reference to the underlying ERC-20 contractfunctionunderlyer() externalviewreturns (address);
/// @return Amount of liquidity that should not be deployed for market making (this liquidity will be used for completing requested withdrawals)functionwithheldLiquidity() externalviewreturns (uint256);
/// @notice Get withdraw requests for an account/// @param account User account to check/// @return minCycle Cycle - block number - that must be active before withdraw is allowed, amount Token amount requestedfunctionrequestedWithdrawals(address account) externalviewreturns (uint256, uint256);
/// @notice Pause deposits on the pool. Withdraws still allowedfunctionpause() external;
/// @notice Unpause deposits on the pool.functionunpause() external;
}
Contract Source Code
File 28 of 71: ILiquidityPool.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;import"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import"../interfaces/IManager.sol";
/// @title Interface for Pool/// @notice Allows users to deposit ERC-20 tokens to be deployed to market makers./// @notice Mints 1:1 fToken on deposit, represeting an IOU for the undelrying token that is freely transferable./// @notice Holders of fTokens earn rewards based on duration their tokens were deployed and the demand for that asset./// @notice Holders of fTokens can redeem for underlying asset after issuing requestWithdrawal and waiting for the next cycle.interfaceILiquidityPool{
structWithdrawalInfo {
uint256 minCycle;
uint256 amount;
}
/// @notice Transfers amount of underlying token from user to this pool and mints fToken to the msg.sender./// @notice Depositor must have previously granted transfer approval to the pool via underlying token contract./// @notice Liquidity deposited is deployed on the next cycle - unless a withdrawal request is submitted, in which case the liquidity will be withheld.functiondeposit(uint256 amount) external;
/// @notice Transfers amount of underlying token from user to this pool and mints fToken to the account./// @notice Depositor must have previously granted transfer approval to the pool via underlying token contract./// @notice Liquidity deposited is deployed on the next cycle - unless a withdrawal request is submitted, in which case the liquidity will be withheld.functiondepositFor(address account, uint256 amount) external;
/// @notice Requests that the manager prepare funds for withdrawal next cycle/// @notice Invoking this function when sender already has a currently pending request will overwrite that requested amount and reset the cycle timer/// @param amount Amount of fTokens requested to be redeemedfunctionrequestWithdrawal(uint256 amount) external;
functionapproveManager(uint256 amount) external;
/// @notice Sender must first invoke requestWithdrawal in a previous cycle/// @notice This function will burn the fAsset and transfers underlying asset back to sender/// @notice Will execute a partial withdrawal if either available liquidity or previously requested amount is insufficient/// @param amount Amount of fTokens to redeem, value can be in excess of available tokens, operation will be reduced to maximum permissiblefunctionwithdraw(uint256 amount) external;
/// @return Reference to the underlying ERC-20 contractfunctionunderlyer() externalviewreturns (ERC20Upgradeable);
/// @return Amount of liquidity that should not be deployed for market making (this liquidity will be used for completing requested withdrawals)functionwithheldLiquidity() externalviewreturns (uint256);
/// @notice Get withdraw requests for an account/// @param account User account to check/// @return minCycle Cycle - block number - that must be active before withdraw is allowed, amount Token amount requestedfunctionrequestedWithdrawals(address account) externalviewreturns (uint256, uint256);
/// @notice Pause deposits on the pool. Withdraws still allowedfunctionpause() external;
/// @notice Unpause deposits on the pool.functionunpause() external;
}
Contract Source Code
File 29 of 71: IManager.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;interfaceIManager{
// bytes can take on the form of deploying or recovering liquiditystructControllerTransferData {
bytes32 controllerId; // controller to targetbytes data; // data the controller will pass
}
structPoolTransferData {
address pool; // pool to targetuint256 amount; // amount to transfer
}
structMaintenanceExecution {
ControllerTransferData[] cycleSteps;
}
structRolloverExecution {
PoolTransferData[] poolData;
ControllerTransferData[] cycleSteps;
address[] poolsForWithdraw; //Pools to target for manager -> pool transferbool complete; //Whether to mark the rollover completestring rewardsIpfsHash;
}
eventControllerRegistered(bytes32 id, address controller);
eventControllerUnregistered(bytes32 id, address controller);
eventPoolRegistered(address pool);
eventPoolUnregistered(address pool);
eventCycleDurationSet(uint256 duration);
eventLiquidityMovedToManager(address pool, uint256 amount);
eventDeploymentStepExecuted(bytes32 controller, address adapaterAddress, bytes data);
eventLiquidityMovedToPool(address pool, uint256 amount);
eventCycleRolloverStarted(uint256 blockNumber);
eventCycleRolloverComplete(uint256 blockNumber);
functionregisterController(bytes32 id, address controller) external;
functionregisterPool(address pool) external;
functionunRegisterController(bytes32 id) external;
functionunRegisterPool(address pool) external;
functiongetPools() externalviewreturns (address[] memory);
functiongetControllers() externalviewreturns (bytes32[] memory);
functionsetCycleDuration(uint256 duration) external;
functionstartCycleRollover() external;
functionexecuteMaintenance(MaintenanceExecution calldata params) external;
functionexecuteRollover(RolloverExecution calldata params) external;
functioncompleteRollover(stringcalldata rewardsIpfsHash) external;
functioncycleRewardsHashes(uint256 index) externalviewreturns (stringmemory);
functiongetCurrentCycle() externalviewreturns (uint256);
functiongetCurrentCycleIndex() externalviewreturns (uint256);
functiongetCycleDuration() externalviewreturns (uint256);
functiongetRolloverStatus() externalviewreturns (bool);
}
Contract Source Code
File 30 of 71: INativeOrdersEvents.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2021 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.
*/pragmasolidity ^0.6.5;pragmaexperimentalABIEncoderV2;import"@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import"../libs/LibSignature.sol";
import"../libs/LibNativeOrder.sol";
/// @dev Events emitted by NativeOrdersFeature.interfaceINativeOrdersEvents{
/// @dev Emitted whenever a `LimitOrder` is filled./// @param orderHash The canonical hash of the order./// @param maker The maker of the order./// @param taker The taker of the order./// @param feeRecipient Fee recipient of the order./// @param takerTokenFilledAmount How much taker token was filled./// @param makerTokenFilledAmount How much maker token was filled./// @param protocolFeePaid How much protocol fee was paid./// @param pool The fee pool associated with this order.eventLimitOrderFilled(bytes32 orderHash,
address maker,
address taker,
address feeRecipient,
address makerToken,
address takerToken,
uint128 takerTokenFilledAmount,
uint128 makerTokenFilledAmount,
uint128 takerTokenFeeFilledAmount,
uint256 protocolFeePaid,
bytes32 pool
);
/// @dev Emitted whenever an `RfqOrder` is filled./// @param orderHash The canonical hash of the order./// @param maker The maker of the order./// @param taker The taker of the order./// @param takerTokenFilledAmount How much taker token was filled./// @param makerTokenFilledAmount How much maker token was filled./// @param pool The fee pool associated with this order.eventRfqOrderFilled(bytes32 orderHash,
address maker,
address taker,
address makerToken,
address takerToken,
uint128 takerTokenFilledAmount,
uint128 makerTokenFilledAmount,
bytes32 pool
);
/// @dev Emitted whenever a limit or RFQ order is cancelled./// @param orderHash The canonical hash of the order./// @param maker The order maker.eventOrderCancelled(bytes32 orderHash,
address maker
);
/// @dev Emitted whenever Limit orders are cancelled by pair by a maker./// @param maker The maker of the order./// @param makerToken The maker token in a pair for the orders cancelled./// @param takerToken The taker token in a pair for the orders cancelled./// @param minValidSalt The new minimum valid salt an order with this pair must/// have.eventPairCancelledLimitOrders(address maker,
address makerToken,
address takerToken,
uint256 minValidSalt
);
/// @dev Emitted whenever RFQ orders are cancelled by pair by a maker./// @param maker The maker of the order./// @param makerToken The maker token in a pair for the orders cancelled./// @param takerToken The taker token in a pair for the orders cancelled./// @param minValidSalt The new minimum valid salt an order with this pair must/// have.eventPairCancelledRfqOrders(address maker,
address makerToken,
address takerToken,
uint256 minValidSalt
);
/// @dev Emitted when new addresses are allowed or disallowed to fill/// orders with a given txOrigin./// @param origin The address doing the allowing./// @param addrs The address being allowed/disallowed./// @param allowed Indicates whether the address should be allowed.eventRfqOrderOriginsAllowed(address origin,
address[] addrs,
bool allowed
);
/// @dev Emitted when new order signers are registered/// @param maker The maker address that is registering a designated signer./// @param signer The address that will sign on behalf of maker./// @param allowed Indicates whether the address should be allowed.eventOrderSignerRegistered(address maker,
address signer,
bool allowed
);
}
Contract Source Code
File 31 of 71: INativeOrdersFeature.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;pragmaexperimentalABIEncoderV2;import"@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import"../libs/LibSignature.sol";
import"../libs/LibNativeOrder.sol";
import"./INativeOrdersEvents.sol";
/// @dev Feature for interacting with limit orders.interfaceINativeOrdersFeatureisINativeOrdersEvents{
/// @dev Transfers protocol fees from the `FeeCollector` pools into/// the staking contract./// @param poolIds Staking pool IDsfunctiontransferProtocolFeesForPools(bytes32[] calldata poolIds)
external;
/// @dev Fill a limit order. The taker and sender will be the caller./// @param order The limit order. ETH protocol fees can be/// attached to this call. Any unspent ETH will be refunded to/// the caller./// @param signature The order signature./// @param takerTokenFillAmount Maximum taker token amount to fill this order with./// @return takerTokenFilledAmount How much maker token was filled./// @return makerTokenFilledAmount How much maker token was filled.functionfillLimitOrder(
LibNativeOrder.LimitOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount
)
externalpayablereturns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Fill an RFQ order for up to `takerTokenFillAmount` taker tokens./// The taker will be the caller./// @param order The RFQ order./// @param signature The order signature./// @param takerTokenFillAmount Maximum taker token amount to fill this order with./// @return takerTokenFilledAmount How much maker token was filled./// @return makerTokenFilledAmount How much maker token was filled.functionfillRfqOrder(
LibNativeOrder.RfqOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount
)
externalreturns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens./// The taker will be the caller. ETH protocol fees can be/// attached to this call. Any unspent ETH will be refunded to/// the caller./// @param order The limit order./// @param signature The order signature./// @param takerTokenFillAmount How much taker token to fill this order with./// @return makerTokenFilledAmount How much maker token was filled.functionfillOrKillLimitOrder(
LibNativeOrder.LimitOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount
)
externalpayablereturns (uint128 makerTokenFilledAmount);
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens./// The taker will be the caller./// @param order The RFQ order./// @param signature The order signature./// @param takerTokenFillAmount How much taker token to fill this order with./// @return makerTokenFilledAmount How much maker token was filled.functionfillOrKillRfqOrder(
LibNativeOrder.RfqOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount
)
externalreturns (uint128 makerTokenFilledAmount);
/// @dev Fill a limit order. Internal variant. ETH protocol fees can be/// attached to this call. Any unspent ETH will be refunded to/// `msg.sender` (not `sender`)./// @param order The limit order./// @param signature The order signature./// @param takerTokenFillAmount Maximum taker token to fill this order with./// @param taker The order taker./// @param sender The order sender./// @return takerTokenFilledAmount How much maker token was filled./// @return makerTokenFilledAmount How much maker token was filled.function_fillLimitOrder(
LibNativeOrder.LimitOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount,
address taker,
address sender
)
externalpayablereturns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Fill an RFQ order. Internal variant./// @param order The RFQ order./// @param signature The order signature./// @param takerTokenFillAmount Maximum taker token to fill this order with./// @param taker The order taker./// @return takerTokenFilledAmount How much maker token was filled./// @return makerTokenFilledAmount How much maker token was filled.function_fillRfqOrder(
LibNativeOrder.RfqOrder calldata order,
LibSignature.Signature calldata signature,
uint128 takerTokenFillAmount,
address taker
)
externalreturns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
/// @dev Cancel a single limit order. The caller must be the maker or a valid order signer./// Silently succeeds if the order has already been cancelled./// @param order The limit order.functioncancelLimitOrder(LibNativeOrder.LimitOrder calldata order)
external;
/// @dev Cancel a single RFQ order. The caller must be the maker or a valid order signer./// Silently succeeds if the order has already been cancelled./// @param order The RFQ order.functioncancelRfqOrder(LibNativeOrder.RfqOrder calldata order)
external;
/// @dev Mark what tx.origin addresses are allowed to fill an order that/// specifies the message sender as its txOrigin./// @param origins An array of origin addresses to update./// @param allowed True to register, false to unregister.functionregisterAllowedRfqOrigins(address[] memory origins, bool allowed)
external;
/// @dev Cancel multiple limit orders. The caller must be the maker or a valid order signer./// Silently succeeds if the order has already been cancelled./// @param orders The limit orders.functionbatchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders)
external;
/// @dev Cancel multiple RFQ orders. The caller must be the maker or a valid order signer./// Silently succeeds if the order has already been cancelled./// @param orders The RFQ orders.functionbatchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders)
external;
/// @dev Cancel all limit orders for a given maker and pair with a salt less/// than the value provided. The caller must be the maker. Subsequent/// calls to this function with the same caller and pair require the/// new salt to be >= the old salt./// @param makerToken The maker token./// @param takerToken The taker token./// @param minValidSalt The new minimum valid salt.functioncancelPairLimitOrders(
IERC20TokenV06 makerToken,
IERC20TokenV06 takerToken,
uint256 minValidSalt
)
external;
/// @dev Cancel all limit orders for a given maker and pair with a salt less/// than the value provided. The caller must be a signer registered to the maker./// Subsequent calls to this function with the same maker and pair require the/// new salt to be >= the old salt./// @param maker The maker for which to cancel./// @param makerToken The maker token./// @param takerToken The taker token./// @param minValidSalt The new minimum valid salt.functioncancelPairLimitOrdersWithSigner(address maker,
IERC20TokenV06 makerToken,
IERC20TokenV06 takerToken,
uint256 minValidSalt
)
external;
/// @dev Cancel all limit orders for a given maker and pairs with salts less/// than the values provided. The caller must be the maker. Subsequent/// calls to this function with the same caller and pair require the/// new salt to be >= the old salt./// @param makerTokens The maker tokens./// @param takerTokens The taker tokens./// @param minValidSalts The new minimum valid salts.functionbatchCancelPairLimitOrders(
IERC20TokenV06[] calldata makerTokens,
IERC20TokenV06[] calldata takerTokens,
uint256[] calldata minValidSalts
)
external;
/// @dev Cancel all limit orders for a given maker and pairs with salts less/// than the values provided. The caller must be a signer registered to the maker./// Subsequent calls to this function with the same maker and pair require the/// new salt to be >= the old salt./// @param maker The maker for which to cancel./// @param makerTokens The maker tokens./// @param takerTokens The taker tokens./// @param minValidSalts The new minimum valid salts.functionbatchCancelPairLimitOrdersWithSigner(address maker,
IERC20TokenV06[] memory makerTokens,
IERC20TokenV06[] memory takerTokens,
uint256[] memory minValidSalts
)
external;
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less/// than the value provided. The caller must be the maker. Subsequent/// calls to this function with the same caller and pair require the/// new salt to be >= the old salt./// @param makerToken The maker token./// @param takerToken The taker token./// @param minValidSalt The new minimum valid salt.functioncancelPairRfqOrders(
IERC20TokenV06 makerToken,
IERC20TokenV06 takerToken,
uint256 minValidSalt
)
external;
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less/// than the value provided. The caller must be a signer registered to the maker./// Subsequent calls to this function with the same maker and pair require the/// new salt to be >= the old salt./// @param maker The maker for which to cancel./// @param makerToken The maker token./// @param takerToken The taker token./// @param minValidSalt The new minimum valid salt.functioncancelPairRfqOrdersWithSigner(address maker,
IERC20TokenV06 makerToken,
IERC20TokenV06 takerToken,
uint256 minValidSalt
)
external;
/// @dev Cancel all RFQ orders for a given maker and pairs with salts less/// than the values provided. The caller must be the maker. Subsequent/// calls to this function with the same caller and pair require the/// new salt to be >= the old salt./// @param makerTokens The maker tokens./// @param takerTokens The taker tokens./// @param minValidSalts The new minimum valid salts.functionbatchCancelPairRfqOrders(
IERC20TokenV06[] calldata makerTokens,
IERC20TokenV06[] calldata takerTokens,
uint256[] calldata minValidSalts
)
external;
/// @dev Cancel all RFQ orders for a given maker and pairs with salts less/// than the values provided. The caller must be a signer registered to the maker./// Subsequent calls to this function with the same maker and pair require the/// new salt to be >= the old salt./// @param maker The maker for which to cancel./// @param makerTokens The maker tokens./// @param takerTokens The taker tokens./// @param minValidSalts The new minimum valid salts.functionbatchCancelPairRfqOrdersWithSigner(address maker,
IERC20TokenV06[] memory makerTokens,
IERC20TokenV06[] memory takerTokens,
uint256[] memory minValidSalts
)
external;
/// @dev Get the order info for a limit order./// @param order The limit order./// @return orderInfo Info about the order.functiongetLimitOrderInfo(LibNativeOrder.LimitOrder calldata order)
externalviewreturns (LibNativeOrder.OrderInfo memory orderInfo);
/// @dev Get the order info for an RFQ order./// @param order The RFQ order./// @return orderInfo Info about the order.functiongetRfqOrderInfo(LibNativeOrder.RfqOrder calldata order)
externalviewreturns (LibNativeOrder.OrderInfo memory orderInfo);
/// @dev Get the canonical hash of a limit order./// @param order The limit order./// @return orderHash The order hash.functiongetLimitOrderHash(LibNativeOrder.LimitOrder calldata order)
externalviewreturns (bytes32 orderHash);
/// @dev Get the canonical hash of an RFQ order./// @param order The RFQ order./// @return orderHash The order hash.functiongetRfqOrderHash(LibNativeOrder.RfqOrder calldata order)
externalviewreturns (bytes32 orderHash);
/// @dev Get the protocol fee multiplier. This should be multiplied by the/// gas price to arrive at the required protocol fee to fill a native order./// @return multiplier The protocol fee multiplier.functiongetProtocolFeeMultiplier()
externalviewreturns (uint32 multiplier);
/// @dev Get order info, fillable amount, and signature validity for a limit order./// Fillable amount is determined using balances and allowances of the maker./// @param order The limit order./// @param signature The order signature./// @return orderInfo Info about the order./// @return actualFillableTakerTokenAmount How much of the order is fillable/// based on maker funds, in taker tokens./// @return isSignatureValid Whether the signature is valid.functiongetLimitOrderRelevantState(
LibNativeOrder.LimitOrder calldata order,
LibSignature.Signature calldata signature
)
externalviewreturns (
LibNativeOrder.OrderInfo memory orderInfo,
uint128 actualFillableTakerTokenAmount,
bool isSignatureValid
);
/// @dev Get order info, fillable amount, and signature validity for an RFQ order./// Fillable amount is determined using balances and allowances of the maker./// @param order The RFQ order./// @param signature The order signature./// @return orderInfo Info about the order./// @return actualFillableTakerTokenAmount How much of the order is fillable/// based on maker funds, in taker tokens./// @return isSignatureValid Whether the signature is valid.functiongetRfqOrderRelevantState(
LibNativeOrder.RfqOrder calldata order,
LibSignature.Signature calldata signature
)
externalviewreturns (
LibNativeOrder.OrderInfo memory orderInfo,
uint128 actualFillableTakerTokenAmount,
bool isSignatureValid
);
/// @dev Batch version of `getLimitOrderRelevantState()`, without reverting./// Orders that would normally cause `getLimitOrderRelevantState()`/// to revert will have empty results./// @param orders The limit orders./// @param signatures The order signatures./// @return orderInfos Info about the orders./// @return actualFillableTakerTokenAmounts How much of each order is fillable/// based on maker funds, in taker tokens./// @return isSignatureValids Whether each signature is valid for the order.functionbatchGetLimitOrderRelevantStates(
LibNativeOrder.LimitOrder[] calldata orders,
LibSignature.Signature[] calldata signatures
)
externalviewreturns (
LibNativeOrder.OrderInfo[] memory orderInfos,
uint128[] memory actualFillableTakerTokenAmounts,
bool[] memory isSignatureValids
);
/// @dev Batch version of `getRfqOrderRelevantState()`, without reverting./// Orders that would normally cause `getRfqOrderRelevantState()`/// to revert will have empty results./// @param orders The RFQ orders./// @param signatures The order signatures./// @return orderInfos Info about the orders./// @return actualFillableTakerTokenAmounts How much of each order is fillable/// based on maker funds, in taker tokens./// @return isSignatureValids Whether each signature is valid for the order.functionbatchGetRfqOrderRelevantStates(
LibNativeOrder.RfqOrder[] calldata orders,
LibSignature.Signature[] calldata signatures
)
externalviewreturns (
LibNativeOrder.OrderInfo[] memory orderInfos,
uint128[] memory actualFillableTakerTokenAmounts,
bool[] memory isSignatureValids
);
/// @dev Register a signer who can sign on behalf of msg.sender/// This allows one to sign on behalf of a contract that calls this function/// @param signer The address from which you plan to generate signatures/// @param allowed True to register, false to unregister.functionregisterAllowedOrderSigner(address signer,
bool allowed
)
external;
/// @dev checks if a given address is registered to sign on behalf of a maker address/// @param maker The maker address encoded in an order (can be a contract)/// @param signer The address that is providing a signaturefunctionisValidOrderSigner(address maker,
address signer
)
externalviewreturns (bool isAllowed);
}
Contract Source Code
File 32 of 71: IStaking.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;interfaceIStaking{
structStakingSchedule {
uint256 cliff; // Duration in seconds before staking startsuint256 duration; // Seconds it takes for entire amount to stakeuint256 interval; // Seconds it takes for a chunk to stakebool setup; //Just so we know its there bool isActive; //Whether we can setup new stakes with the scheduleuint256 hardStart; //Stakings will always start at this timestamp if set bool isPublic; //Schedule can be written to by any account
}
structStakingScheduleInfo {
StakingSchedule schedule;
uint256 index;
}
structStakingDetails {
uint256 initial; //Initial amount of asset when stake was created, total amount to be staked before slashinguint256 withdrawn; //Amount that was staked and subsequently withdrawnuint256 slashed; //Amount that has been slashed uint256 started; //Timestamp at which the stake starteduint256 scheduleIx;
}
structWithdrawalInfo {
uint256 minCycleIndex;
uint256 amount;
}
eventScheduleAdded(uint256 scheduleIndex, uint256 cliff, uint256 duration, uint256 interval, bool setup, bool isActive, uint256 hardStart);
eventScheduleRemoved(uint256 scheduleIndex);
eventWithdrawalRequested(address account, uint256 amount);
eventWithdrawCompleted(address account, uint256 amount);
eventDeposited(address account, uint256 amount, uint256 scheduleIx);
eventSlashed(address account, uint256 amount, uint256 scheduleIx);
functionpermissionedDepositors(address account) externalreturns (bool);
functionsetUserSchedules(address account, uint256[] calldata userSchedulesIdxs) external;
functionaddSchedule(StakingSchedule memory schedule) external;
functiongetSchedules() externalviewreturns (StakingScheduleInfo[] memory);
functionsetPermissionedDepositor(address account, bool canDeposit) external;
functionremoveSchedule(uint256 scheduleIndex) external;
functiongetStakes(address account) externalviewreturns(StakingDetails[] memory);
functionbalanceOf(address account) externalviewreturns(uint256);
functionavailableForWithdrawal(address account, uint256 scheduleIndex) externalviewreturns (uint256);
functionunvested(address account, uint256 scheduleIndex) externalviewreturns(uint256);
functionvested(address account, uint256 scheduleIndex) externalviewreturns(uint256);
functiondeposit(uint256 amount, uint256 scheduleIndex) external;
functiondepositFor(address account, uint256 amount, uint256 scheduleIndex) external;
functiondepositWithSchedule(address account, uint256 amount, StakingSchedule calldata schedule) external;
functionrequestWithdrawal(uint256 amount) external;
functionwithdraw(uint256 amount) external;
/// @notice Pause deposits on the pool. Withdraws still allowedfunctionpause() external;
/// @notice Unpause deposits on the pool.functionunpause() external;
}
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;// We import the contract so truffle compiles it, and we have the ABI// available when working from truffle console.import"@gnosis.pm/mock-contract/contracts/MockContract.sol";
import"@openzeppelin/contracts/token/ERC20/ERC20.sol";
import"@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol";
import"@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import"@uniswap/v2-core/contracts/interfaces/IUniswapV2ERC20.sol";
import"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import"@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Router02.sol"asISushiswapV2Router;
import"@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Factory.sol"asISushiswapV2Factory;
import"@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2ERC20.sol"asISushiswapV2ERC20;
Contract Source Code
File 40 of 71: Initializable.sol
// SPDX-License-Identifier: MIT// solhint-disable-next-line compiler-versionpragmasolidity >=0.4.24 <0.8.0;import"../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/abstractcontractInitializable{
/**
* @dev Indicates that the contract has been initialized.
*/boolprivate _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/boolprivate _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/modifierinitializer() {
require(_initializing || _isConstructor() ||!_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall =!_initializing;
if (isTopLevelCall) {
_initializing =true;
_initialized =true;
}
_;
if (isTopLevelCall) {
_initializing =false;
}
}
/// @dev Returns true if and only if the function is running in the constructorfunction_isConstructor() privateviewreturns (bool) {
return!AddressUpgradeable.isContract(address(this));
}
}
Contract Source Code
File 41 of 71: LibNativeOrder.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;pragmaexperimentalABIEncoderV2;import"@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import"@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import"@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import"../../errors/LibNativeOrdersRichErrors.sol";
/// @dev A library for common native order operations.libraryLibNativeOrder{
usingLibSafeMathV06foruint256;
usingLibRichErrorsV06forbytes;
enumOrderStatus {
INVALID,
FILLABLE,
FILLED,
CANCELLED,
EXPIRED
}
/// @dev A standard OTC or OO limit order.structLimitOrder {
IERC20TokenV06 makerToken;
IERC20TokenV06 takerToken;
uint128 makerAmount;
uint128 takerAmount;
uint128 takerTokenFeeAmount;
address maker;
address taker;
address sender;
address feeRecipient;
bytes32 pool;
uint64 expiry;
uint256 salt;
}
/// @dev An RFQ limit order.structRfqOrder {
IERC20TokenV06 makerToken;
IERC20TokenV06 takerToken;
uint128 makerAmount;
uint128 takerAmount;
address maker;
address taker;
address txOrigin;
bytes32 pool;
uint64 expiry;
uint256 salt;
}
/// @dev An OTC limit order.structOtcOrder {
IERC20TokenV06 makerToken;
IERC20TokenV06 takerToken;
uint128 makerAmount;
uint128 takerAmount;
address maker;
address taker;
address txOrigin;
uint256 expiryAndNonce; // [uint64 expiry, uint64 nonceBucket, uint128 nonce]
}
/// @dev Info on a limit or RFQ order.structOrderInfo {
bytes32 orderHash;
OrderStatus status;
uint128 takerTokenFilledAmount;
}
/// @dev Info on an OTC order.structOtcOrderInfo {
bytes32 orderHash;
OrderStatus status;
}
uint256privateconstant UINT_128_MASK = (1<<128) -1;
uint256privateconstant UINT_64_MASK = (1<<64) -1;
uint256privateconstant ADDRESS_MASK = (1<<160) -1;
// The type hash for limit orders, which is:// keccak256(abi.encodePacked(// "LimitOrder(",// "address makerToken,",// "address takerToken,",// "uint128 makerAmount,",// "uint128 takerAmount,",// "uint128 takerTokenFeeAmount,",// "address maker,",// "address taker,",// "address sender,",// "address feeRecipient,",// "bytes32 pool,",// "uint64 expiry,",// "uint256 salt"// ")"// ))uint256privateconstant _LIMIT_ORDER_TYPEHASH =0xce918627cb55462ddbb85e73de69a8b322f2bc88f4507c52fcad6d4c33c29d49;
// The type hash for RFQ orders, which is:// keccak256(abi.encodePacked(// "RfqOrder(",// "address makerToken,",// "address takerToken,",// "uint128 makerAmount,",// "uint128 takerAmount,",// "address maker,",// "address taker,",// "address txOrigin,",// "bytes32 pool,",// "uint64 expiry,",// "uint256 salt"// ")"// ))uint256privateconstant _RFQ_ORDER_TYPEHASH =0xe593d3fdfa8b60e5e17a1b2204662ecbe15c23f2084b9ad5bae40359540a7da9;
// The type hash for OTC orders, which is:// keccak256(abi.encodePacked(// "OtcOrder(",// "address makerToken,",// "address takerToken,",// "uint128 makerAmount,",// "uint128 takerAmount,",// "address maker,",// "address taker,",// "address txOrigin,",// "uint256 expiryAndNonce"// ")"// ))uint256privateconstant _OTC_ORDER_TYPEHASH =0x2f754524de756ae72459efbe1ec88c19a745639821de528ac3fb88f9e65e35c8;
/// @dev Get the struct hash of a limit order./// @param order The limit order./// @return structHash The struct hash of the order.functiongetLimitOrderStructHash(LimitOrder memory order)
internalpurereturns (bytes32 structHash)
{
// The struct hash is:// keccak256(abi.encode(// TYPE_HASH,// order.makerToken,// order.takerToken,// order.makerAmount,// order.takerAmount,// order.takerTokenFeeAmount,// order.maker,// order.taker,// order.sender,// order.feeRecipient,// order.pool,// order.expiry,// order.salt,// ))assembly {
let mem :=mload(0x40)
mstore(mem, _LIMIT_ORDER_TYPEHASH)
// order.makerToken;mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order)))
// order.takerToken;mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20))))
// order.makerAmount;mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40))))
// order.takerAmount;mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
// order.takerTokenFeeAmount;mstore(add(mem, 0xA0), and(UINT_128_MASK, mload(add(order, 0x80))))
// order.maker;mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
// order.taker;mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
// order.sender;mstore(add(mem, 0x100), and(ADDRESS_MASK, mload(add(order, 0xE0))))
// order.feeRecipient;mstore(add(mem, 0x120), and(ADDRESS_MASK, mload(add(order, 0x100))))
// order.pool;mstore(add(mem, 0x140), mload(add(order, 0x120)))
// order.expiry;mstore(add(mem, 0x160), and(UINT_64_MASK, mload(add(order, 0x140))))
// order.salt;mstore(add(mem, 0x180), mload(add(order, 0x160)))
structHash :=keccak256(mem, 0x1A0)
}
}
/// @dev Get the struct hash of a RFQ order./// @param order The RFQ order./// @return structHash The struct hash of the order.functiongetRfqOrderStructHash(RfqOrder memory order)
internalpurereturns (bytes32 structHash)
{
// The struct hash is:// keccak256(abi.encode(// TYPE_HASH,// order.makerToken,// order.takerToken,// order.makerAmount,// order.takerAmount,// order.maker,// order.taker,// order.txOrigin,// order.pool,// order.expiry,// order.salt,// ))assembly {
let mem :=mload(0x40)
mstore(mem, _RFQ_ORDER_TYPEHASH)
// order.makerToken;mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order)))
// order.takerToken;mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20))))
// order.makerAmount;mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40))))
// order.takerAmount;mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
// order.maker;mstore(add(mem, 0xA0), and(ADDRESS_MASK, mload(add(order, 0x80))))
// order.taker;mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
// order.txOrigin;mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
// order.pool;mstore(add(mem, 0x100), mload(add(order, 0xE0)))
// order.expiry;mstore(add(mem, 0x120), and(UINT_64_MASK, mload(add(order, 0x100))))
// order.salt;mstore(add(mem, 0x140), mload(add(order, 0x120)))
structHash :=keccak256(mem, 0x160)
}
}
/// @dev Get the struct hash of an OTC order./// @param order The OTC order./// @return structHash The struct hash of the order.functiongetOtcOrderStructHash(OtcOrder memory order)
internalpurereturns (bytes32 structHash)
{
// The struct hash is:// keccak256(abi.encode(// TYPE_HASH,// order.makerToken,// order.takerToken,// order.makerAmount,// order.takerAmount,// order.maker,// order.taker,// order.txOrigin,// order.expiryAndNonce,// ))assembly {
let mem :=mload(0x40)
mstore(mem, _OTC_ORDER_TYPEHASH)
// order.makerToken;mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order)))
// order.takerToken;mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20))))
// order.makerAmount;mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40))))
// order.takerAmount;mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
// order.maker;mstore(add(mem, 0xA0), and(ADDRESS_MASK, mload(add(order, 0x80))))
// order.taker;mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
// order.txOrigin;mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
// order.expiryAndNonce;mstore(add(mem, 0x100), mload(add(order, 0xE0)))
structHash :=keccak256(mem, 0x120)
}
}
/// @dev Refund any leftover protocol fees in `msg.value` to `msg.sender`./// @param ethProtocolFeePaid How much ETH was paid in protocol fees.functionrefundExcessProtocolFeeToSender(uint256 ethProtocolFeePaid)
internal{
if (msg.value> ethProtocolFeePaid &&msg.sender!=address(this)) {
uint256 refundAmount =msg.value.safeSub(ethProtocolFeePaid);
(bool success,) =msg
.sender
.call{value: refundAmount}("");
if (!success) {
LibNativeOrdersRichErrors.ProtocolFeeRefundFailed(
msg.sender,
refundAmount
).rrevert();
}
}
}
}
Contract Source Code
File 42 of 71: LibNativeOrdersRichErrors.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;libraryLibNativeOrdersRichErrors{
// solhint-disable func-name-mixedcasefunctionProtocolFeeRefundFailed(address receiver,
uint256 refundAmount
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("ProtocolFeeRefundFailed(address,uint256)")),
receiver,
refundAmount
);
}
functionOrderNotFillableByOriginError(bytes32 orderHash,
address txOrigin,
address orderTxOrigin
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OrderNotFillableByOriginError(bytes32,address,address)")),
orderHash,
txOrigin,
orderTxOrigin
);
}
functionOrderNotFillableError(bytes32 orderHash,
uint8 orderStatus
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OrderNotFillableError(bytes32,uint8)")),
orderHash,
orderStatus
);
}
functionOrderNotSignedByMakerError(bytes32 orderHash,
address signer,
address maker
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OrderNotSignedByMakerError(bytes32,address,address)")),
orderHash,
signer,
maker
);
}
functionOrderNotSignedByTakerError(bytes32 orderHash,
address signer,
address taker
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OrderNotSignedByTakerError(bytes32,address,address)")),
orderHash,
signer,
taker
);
}
functionInvalidSignerError(address maker,
address signer
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("InvalidSignerError(address,address)")),
maker,
signer
);
}
functionOrderNotFillableBySenderError(bytes32 orderHash,
address sender,
address orderSender
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OrderNotFillableBySenderError(bytes32,address,address)")),
orderHash,
sender,
orderSender
);
}
functionOrderNotFillableByTakerError(bytes32 orderHash,
address taker,
address orderTaker
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OrderNotFillableByTakerError(bytes32,address,address)")),
orderHash,
taker,
orderTaker
);
}
functionCancelSaltTooLowError(uint256 minValidSalt,
uint256 oldMinValidSalt
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("CancelSaltTooLowError(uint256,uint256)")),
minValidSalt,
oldMinValidSalt
);
}
functionFillOrKillFailedError(bytes32 orderHash,
uint256 takerTokenFilledAmount,
uint256 takerTokenFillAmount
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("FillOrKillFailedError(bytes32,uint256,uint256)")),
orderHash,
takerTokenFilledAmount,
takerTokenFillAmount
);
}
functionOnlyOrderMakerAllowed(bytes32 orderHash,
address sender,
address maker
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("OnlyOrderMakerAllowed(bytes32,address,address)")),
orderHash,
sender,
maker
);
}
functionBatchFillIncompleteError(bytes32 orderHash,
uint256 takerTokenFilledAmount,
uint256 takerTokenFillAmount
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("BatchFillIncompleteError(bytes32,uint256,uint256)")),
orderHash,
takerTokenFilledAmount,
takerTokenFillAmount
);
}
}
Contract Source Code
File 43 of 71: LibRichErrorsV06.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;libraryLibRichErrorsV06{
// bytes4(keccak256("Error(string)"))bytes4internalconstant STANDARD_ERROR_SELECTOR =0x08c379a0;
// solhint-disable func-name-mixedcase/// @dev ABI encode a standard, string revert error payload./// This is the same payload that would be included by a `revert(string)`/// solidity statement. It has the function signature `Error(string)`./// @param message The error string./// @return The ABI encoded error.functionStandardError(stringmemory message)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
STANDARD_ERROR_SELECTOR,
bytes(message)
);
}
// solhint-enable func-name-mixedcase/// @dev Reverts an encoded rich revert reason `errorData`./// @param errorData ABI encoded error data.functionrrevert(bytesmemory errorData)
internalpure{
assembly {
revert(add(errorData, 0x20), mload(errorData))
}
}
}
Contract Source Code
File 44 of 71: LibSafeMathRichErrorsV06.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;libraryLibSafeMathRichErrorsV06{
// bytes4(keccak256("Uint256BinOpError(uint8,uint256,uint256)"))bytes4internalconstant UINT256_BINOP_ERROR_SELECTOR =0xe946c1bb;
// bytes4(keccak256("Uint256DowncastError(uint8,uint256)"))bytes4internalconstant UINT256_DOWNCAST_ERROR_SELECTOR =0xc996af7b;
enumBinOpErrorCodes {
ADDITION_OVERFLOW,
MULTIPLICATION_OVERFLOW,
SUBTRACTION_UNDERFLOW,
DIVISION_BY_ZERO
}
enumDowncastErrorCodes {
VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT32,
VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT64,
VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT96,
VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT128
}
// solhint-disable func-name-mixedcasefunctionUint256BinOpError(
BinOpErrorCodes errorCode,
uint256 a,
uint256 b
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
UINT256_BINOP_ERROR_SELECTOR,
errorCode,
a,
b
);
}
functionUint256DowncastError(
DowncastErrorCodes errorCode,
uint256 a
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
UINT256_DOWNCAST_ERROR_SELECTOR,
errorCode,
a
);
}
}
Contract Source Code
File 45 of 71: LibSafeMathV06.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;import"./errors/LibRichErrorsV06.sol";
import"./errors/LibSafeMathRichErrorsV06.sol";
libraryLibSafeMathV06{
functionsafeMul(uint256 a, uint256 b)
internalpurereturns (uint256)
{
if (a ==0) {
return0;
}
uint256 c = a * b;
if (c / a != b) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.MULTIPLICATION_OVERFLOW,
a,
b
));
}
return c;
}
functionsafeDiv(uint256 a, uint256 b)
internalpurereturns (uint256)
{
if (b ==0) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.DIVISION_BY_ZERO,
a,
b
));
}
uint256 c = a / b;
return c;
}
functionsafeSub(uint256 a, uint256 b)
internalpurereturns (uint256)
{
if (b > a) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.SUBTRACTION_UNDERFLOW,
a,
b
));
}
return a - b;
}
functionsafeAdd(uint256 a, uint256 b)
internalpurereturns (uint256)
{
uint256 c = a + b;
if (c < a) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.ADDITION_OVERFLOW,
a,
b
));
}
return c;
}
functionmax256(uint256 a, uint256 b)
internalpurereturns (uint256)
{
return a >= b ? a : b;
}
functionmin256(uint256 a, uint256 b)
internalpurereturns (uint256)
{
return a < b ? a : b;
}
functionsafeMul128(uint128 a, uint128 b)
internalpurereturns (uint128)
{
if (a ==0) {
return0;
}
uint128 c = a * b;
if (c / a != b) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.MULTIPLICATION_OVERFLOW,
a,
b
));
}
return c;
}
functionsafeDiv128(uint128 a, uint128 b)
internalpurereturns (uint128)
{
if (b ==0) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.DIVISION_BY_ZERO,
a,
b
));
}
uint128 c = a / b;
return c;
}
functionsafeSub128(uint128 a, uint128 b)
internalpurereturns (uint128)
{
if (b > a) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.SUBTRACTION_UNDERFLOW,
a,
b
));
}
return a - b;
}
functionsafeAdd128(uint128 a, uint128 b)
internalpurereturns (uint128)
{
uint128 c = a + b;
if (c < a) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
LibSafeMathRichErrorsV06.BinOpErrorCodes.ADDITION_OVERFLOW,
a,
b
));
}
return c;
}
functionmax128(uint128 a, uint128 b)
internalpurereturns (uint128)
{
return a >= b ? a : b;
}
functionmin128(uint128 a, uint128 b)
internalpurereturns (uint128)
{
return a < b ? a : b;
}
functionsafeDowncastToUint128(uint256 a)
internalpurereturns (uint128)
{
if (a >type(uint128).max) {
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256DowncastError(
LibSafeMathRichErrorsV06.DowncastErrorCodes.VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT128,
a
));
}
returnuint128(a);
}
}
Contract Source Code
File 46 of 71: LibSignature.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;pragmaexperimentalABIEncoderV2;import"@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import"../../errors/LibSignatureRichErrors.sol";
/// @dev A library for validating signatures.libraryLibSignature{
usingLibRichErrorsV06forbytes;
// '\x19Ethereum Signed Message:\n32\x00\x00\x00\x00' in a word.uint256privateconstant ETH_SIGN_HASH_PREFIX =0x19457468657265756d205369676e6564204d6573736167653a0a333200000000;
/// @dev Exclusive upper limit on ECDSA signatures 'R' values./// The valid range is given by fig (282) of the yellow paper.uint256privateconstant ECDSA_SIGNATURE_R_LIMIT =uint256(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141);
/// @dev Exclusive upper limit on ECDSA signatures 'S' values./// The valid range is given by fig (283) of the yellow paper.uint256privateconstant ECDSA_SIGNATURE_S_LIMIT = ECDSA_SIGNATURE_R_LIMIT /2+1;
/// @dev Allowed signature types.enumSignatureType {
ILLEGAL,
INVALID,
EIP712,
ETHSIGN
}
/// @dev Encoded EC signature.structSignature {
// How to validate the signature.
SignatureType signatureType;
// EC Signature data.uint8 v;
// EC Signature data.bytes32 r;
// EC Signature data.bytes32 s;
}
/// @dev Retrieve the signer of a signature./// Throws if the signature can't be validated./// @param hash The hash that was signed./// @param signature The signature./// @return recovered The recovered signer address.functiongetSignerOfHash(bytes32 hash,
Signature memory signature
)
internalpurereturns (address recovered)
{
// Ensure this is a signature type that can be validated against a hash.
_validateHashCompatibleSignature(hash, signature);
if (signature.signatureType == SignatureType.EIP712) {
// Signed using EIP712
recovered =ecrecover(
hash,
signature.v,
signature.r,
signature.s
);
} elseif (signature.signatureType == SignatureType.ETHSIGN) {
// Signed using `eth_sign`// Need to hash `hash` with "\x19Ethereum Signed Message:\n32" prefix// in packed encoding.bytes32 ethSignHash;
assembly {
// Use scratch spacemstore(0, ETH_SIGN_HASH_PREFIX) // length of 28 bytesmstore(28, hash) // length of 32 bytes
ethSignHash :=keccak256(0, 60)
}
recovered =ecrecover(
ethSignHash,
signature.v,
signature.r,
signature.s
);
}
// `recovered` can be null if the signature values are out of range.if (recovered ==address(0)) {
LibSignatureRichErrors.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.BAD_SIGNATURE_DATA,
hash
).rrevert();
}
}
/// @dev Validates that a signature is compatible with a hash signee./// @param hash The hash that was signed./// @param signature The signature.function_validateHashCompatibleSignature(bytes32 hash,
Signature memory signature
)
privatepure{
// Ensure the r and s are within malleability limits.if (uint256(signature.r) >= ECDSA_SIGNATURE_R_LIMIT ||uint256(signature.s) >= ECDSA_SIGNATURE_S_LIMIT)
{
LibSignatureRichErrors.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.BAD_SIGNATURE_DATA,
hash
).rrevert();
}
// Always illegal signature.if (signature.signatureType == SignatureType.ILLEGAL) {
LibSignatureRichErrors.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.ILLEGAL,
hash
).rrevert();
}
// Always invalid.if (signature.signatureType == SignatureType.INVALID) {
LibSignatureRichErrors.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.ALWAYS_INVALID,
hash
).rrevert();
}
// Solidity should check that the signature type is within enum range for us// when abi-decoding.
}
}
Contract Source Code
File 47 of 71: LibSignatureRichErrors.sol
// SPDX-License-Identifier: Apache-2.0/*
Copyright 2020 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.
*/pragmasolidity ^0.6.5;libraryLibSignatureRichErrors{
enumSignatureValidationErrorCodes {
ALWAYS_INVALID,
INVALID_LENGTH,
UNSUPPORTED,
ILLEGAL,
WRONG_SIGNER,
BAD_SIGNATURE_DATA
}
// solhint-disable func-name-mixedcasefunctionSignatureValidationError(
SignatureValidationErrorCodes code,
bytes32 hash,
address signerAddress,
bytesmemory signature
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("SignatureValidationError(uint8,bytes32,address,bytes)")),
code,
hash,
signerAddress,
signature
);
}
functionSignatureValidationError(
SignatureValidationErrorCodes code,
bytes32 hash
)
internalpurereturns (bytesmemory)
{
returnabi.encodeWithSelector(
bytes4(keccak256("SignatureValidationError(uint8,bytes32)")),
code,
hash
);
}
}
Contract Source Code
File 48 of 71: Manager.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;pragmaexperimentalABIEncoderV2;import"../interfaces/IManager.sol";
import"../interfaces/ILiquidityPool.sol";
import"@openzeppelin/contracts/utils/Address.sol";
import"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import {IERC20UpgradeableasIERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20UpgradeableasSafeERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol";
import {EnumerableSetUpgradeableasEnumerableSet} from"@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol";
import {SafeMathUpgradeableasSafeMath} from"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import {AccessControlUpgradeableasAccessControl} from"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
contractManagerisIManager, Initializable, AccessControl{
usingSafeMathforuint256;
usingSafeERC20forIERC20;
usingAddressforaddress;
usingEnumerableSetforEnumerableSet.AddressSet;
usingEnumerableSetforEnumerableSet.Bytes32Set;
bytes32publicconstant ADMIN_ROLE =keccak256("ADMIN_ROLE");
bytes32publicconstant ROLLOVER_ROLE =keccak256("ROLLOVER_ROLE");
bytes32publicconstant MID_CYCLE_ROLE =keccak256("MID_CYCLE_ROLE");
uint256public currentCycle;
uint256public currentCycleIndex;
uint256public cycleDuration;
boolpublic rolloverStarted;
mapping(bytes32=>address) public registeredControllers;
mapping(uint256=>string) publicoverride cycleRewardsHashes;
EnumerableSet.AddressSet private pools;
EnumerableSet.Bytes32Set private controllerIds;
modifieronlyAdmin() {
require(hasRole(ADMIN_ROLE, _msgSender()), "NOT_ADMIN_ROLE");
_;
}
modifieronlyRollover() {
require(hasRole(ROLLOVER_ROLE, _msgSender()), "NOT_ROLLOVER_ROLE");
_;
}
modifieronlyMidCycle() {
require(hasRole(MID_CYCLE_ROLE, _msgSender()), "NOT_MID_CYCLE_ROLE");
_;
}
functioninitialize(uint256 _cycleDuration) publicinitializer{
__Context_init_unchained();
__AccessControl_init_unchained();
cycleDuration = _cycleDuration;
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(ADMIN_ROLE, _msgSender());
_setupRole(ROLLOVER_ROLE, _msgSender());
_setupRole(MID_CYCLE_ROLE, _msgSender());
}
functionregisterController(bytes32 id, address controller) externaloverrideonlyAdmin{
require(!controllerIds.contains(id), "CONTROLLER_EXISTS");
registeredControllers[id] = controller;
controllerIds.add(id);
emit ControllerRegistered(id, controller);
}
functionunRegisterController(bytes32 id) externaloverrideonlyAdmin{
require(controllerIds.contains(id), "INVALID_CONTROLLER");
emit ControllerUnregistered(id, registeredControllers[id]);
delete registeredControllers[id];
controllerIds.remove(id);
}
functionregisterPool(address pool) externaloverrideonlyAdmin{
require(!pools.contains(pool), "POOL_EXISTS");
pools.add(pool);
emit PoolRegistered(pool);
}
functionunRegisterPool(address pool) externaloverrideonlyAdmin{
require(pools.contains(pool), "INVALID_POOL");
pools.remove(pool);
emit PoolUnregistered(pool);
}
functionsetCycleDuration(uint256 duration) externaloverrideonlyAdmin{
cycleDuration = duration;
emit CycleDurationSet(duration);
}
functiongetPools() externalviewoverridereturns (address[] memory) {
address[] memory returnData =newaddress[](pools.length());
for (uint256 i =0; i < pools.length(); i++) {
returnData[i] = pools.at(i);
}
return returnData;
}
functiongetControllers() externalviewoverridereturns (bytes32[] memory) {
bytes32[] memory returnData =newbytes32[](controllerIds.length());
for (uint256 i =0; i < controllerIds.length(); i++) {
returnData[i] = controllerIds.at(i);
}
return returnData;
}
functioncompleteRollover(stringcalldata rewardsIpfsHash) externaloverrideonlyRollover{
require(block.number> (currentCycle.add(cycleDuration)), "PREMATURE_EXECUTION");
_completeRollover(rewardsIpfsHash);
}
functionexecuteMaintenance(MaintenanceExecution calldata params)
externaloverrideonlyMidCycle{
for (uint256 x =0; x < params.cycleSteps.length; x++) {
_executeControllerCommand(params.cycleSteps[x]);
}
}
functionexecuteRollover(RolloverExecution calldata params) externaloverrideonlyRollover{
require(block.number> (currentCycle.add(cycleDuration)), "PREMATURE_EXECUTION");
// Transfer deployable liquidity out of the pools and into the managerfor (uint256 i =0; i < params.poolData.length; i++) {
require(pools.contains(params.poolData[i].pool), "INVALID_POOL");
ILiquidityPool pool = ILiquidityPool(params.poolData[i].pool);
IERC20 underlyingToken = pool.underlyer();
underlyingToken.safeTransferFrom(
address(pool),
address(this),
params.poolData[i].amount
);
emit LiquidityMovedToManager(params.poolData[i].pool, params.poolData[i].amount);
}
// Deploy or withdraw liquidityfor (uint256 x =0; x < params.cycleSteps.length; x++) {
_executeControllerCommand(params.cycleSteps[x]);
}
// Transfer recovered liquidity back into the pools; leave no funds in the managerfor (uint256 y =0; y < params.poolsForWithdraw.length; y++) {
require(pools.contains(params.poolsForWithdraw[y]), "INVALID_POOL");
ILiquidityPool pool = ILiquidityPool(params.poolsForWithdraw[y]);
IERC20 underlyingToken = pool.underlyer();
uint256 managerBalance = underlyingToken.balanceOf(address(this));
// transfer funds back to the pool if there are fundsif (managerBalance >0) {
underlyingToken.safeTransfer(address(pool), managerBalance);
}
emit LiquidityMovedToPool(params.poolsForWithdraw[y], managerBalance);
}
if (params.complete) {
_completeRollover(params.rewardsIpfsHash);
}
}
function_executeControllerCommand(ControllerTransferData calldata transfer) private{
address controllerAddress = registeredControllers[transfer.controllerId];
require(controllerAddress !=address(0), "INVALID_CONTROLLER");
controllerAddress.functionDelegateCall(transfer.data, "CYCLE_STEP_EXECUTE_FAILED");
emit DeploymentStepExecuted(transfer.controllerId, controllerAddress, transfer.data);
}
functionstartCycleRollover() externaloverrideonlyRollover{
rolloverStarted =true;
emit CycleRolloverStarted(block.number);
}
function_completeRollover(stringcalldata rewardsIpfsHash) private{
currentCycle =block.number;
cycleRewardsHashes[currentCycleIndex] = rewardsIpfsHash;
currentCycleIndex = currentCycleIndex.add(1);
rolloverStarted =false;
emit CycleRolloverComplete(block.number);
}
functiongetCurrentCycle() externalviewoverridereturns (uint256) {
return currentCycle;
}
functiongetCycleDuration() externalviewoverridereturns (uint256) {
return cycleDuration;
}
functiongetCurrentCycleIndex() externalviewoverridereturns (uint256) {
return currentCycleIndex;
}
functiongetRolloverStatus() externalviewoverridereturns (bool) {
return rolloverStarted;
}
}
Contract Source Code
File 49 of 71: Math.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Standard math utilities missing in the Solidity language.
*/libraryMath{
/**
* @dev Returns the largest of two numbers.
*/functionmax(uint256 a, uint256 b) internalpurereturns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/functionmin(uint256 a, uint256 b) internalpurereturns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/functionaverage(uint256 a, uint256 b) internalpurereturns (uint256) {
// (a + b) / 2 can overflow, so we distributereturn (a /2) + (b /2) + ((a %2+ b %2) /2);
}
}
Contract Source Code
File 50 of 71: MathUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Standard math utilities missing in the Solidity language.
*/libraryMathUpgradeable{
/**
* @dev Returns the largest of two numbers.
*/functionmax(uint256 a, uint256 b) internalpurereturns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/functionmin(uint256 a, uint256 b) internalpurereturns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/functionaverage(uint256 a, uint256 b) internalpurereturns (uint256) {
// (a + b) / 2 can overflow, so we distributereturn (a /2) + (b /2) + ((a %2+ b %2) /2);
}
}
Contract Source Code
File 51 of 71: MerkleProof.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev These functions deal with verification of Merkle trees (hash trees),
*/libraryMerkleProof{
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/functionverify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internalpurereturns (bool) {
bytes32 computedHash = leaf;
for (uint256 i =0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash =keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash =keccak256(abi.encodePacked(proofElement, computedHash));
}
}
// Check if the computed hash (root) is equal to the provided rootreturn computedHash == root;
}
}
Contract Source Code
File 52 of 71: MockContract.sol
pragmasolidity ^0.6.0;interfaceMockInterface{
/**
* @dev After calling this method, the mock will return `response` when it is called
* with any calldata that is not mocked more specifically below
* (e.g. using givenMethodReturn).
* @param response ABI encoded response that will be returned if method is invoked
*/functiongivenAnyReturn(bytescalldata response) external;
functiongivenAnyReturnBool(bool response) external;
functiongivenAnyReturnUint(uint response) external;
functiongivenAnyReturnAddress(address response) external;
functiongivenAnyRevert() external;
functiongivenAnyRevertWithMessage(stringcalldata message) external;
functiongivenAnyRunOutOfGas() external;
/**
* @dev After calling this method, the mock will return `response` when the given
* methodId is called regardless of arguments. If the methodId and arguments
* are mocked more specifically (using `givenMethodAndArguments`) the latter
* will take precedence.
* @param method ABI encoded methodId. It is valid to pass full calldata (including arguments). The mock will extract the methodId from it
* @param response ABI encoded response that will be returned if method is invoked
*/functiongivenMethodReturn(bytescalldata method, bytescalldata response) external;
functiongivenMethodReturnBool(bytescalldata method, bool response) external;
functiongivenMethodReturnUint(bytescalldata method, uint response) external;
functiongivenMethodReturnAddress(bytescalldata method, address response) external;
functiongivenMethodRevert(bytescalldata method) external;
functiongivenMethodRevertWithMessage(bytescalldata method, stringcalldata message) external;
functiongivenMethodRunOutOfGas(bytescalldata method) external;
/**
* @dev After calling this method, the mock will return `response` when the given
* methodId is called with matching arguments. These exact calldataMocks will take
* precedence over all other calldataMocks.
* @param call ABI encoded calldata (methodId and arguments)
* @param response ABI encoded response that will be returned if contract is invoked with calldata
*/functiongivenCalldataReturn(bytescalldata call, bytescalldata response) external;
functiongivenCalldataReturnBool(bytescalldata call, bool response) external;
functiongivenCalldataReturnUint(bytescalldata call, uint response) external;
functiongivenCalldataReturnAddress(bytescalldata call, address response) external;
functiongivenCalldataRevert(bytescalldata call) external;
functiongivenCalldataRevertWithMessage(bytescalldata call, stringcalldata message) external;
functiongivenCalldataRunOutOfGas(bytescalldata call) external;
/**
* @dev Returns the number of times anything has been called on this mock since last reset
*/functioninvocationCount() externalreturns (uint);
/**
* @dev Returns the number of times the given method has been called on this mock since last reset
* @param method ABI encoded methodId. It is valid to pass full calldata (including arguments). The mock will extract the methodId from it
*/functioninvocationCountForMethod(bytescalldata method) externalreturns (uint);
/**
* @dev Returns the number of times this mock has been called with the exact calldata since last reset.
* @param call ABI encoded calldata (methodId and arguments)
*/functioninvocationCountForCalldata(bytescalldata call) externalreturns (uint);
/**
* @dev Resets all mocked methods and invocation counts.
*/functionreset() external;
}
/**
* Implementation of the MockInterface.
*/contractMockContractisMockInterface{
enumMockType { Return, Revert, OutOfGas }
bytes32publicconstant MOCKS_LIST_START =hex"01";
bytespublicconstant MOCKS_LIST_END ="0xff";
bytes32publicconstant MOCKS_LIST_END_HASH =keccak256(MOCKS_LIST_END);
bytes4publicconstant SENTINEL_ANY_MOCKS =hex"01";
bytespublicconstant DEFAULT_FALLBACK_VALUE =abi.encode(false);
// A linked list allows easy iteration and inclusion checksmapping(bytes32=>bytes) calldataMocks;
mapping(bytes=> MockType) calldataMockTypes;
mapping(bytes=>bytes) calldataExpectations;
mapping(bytes=>string) calldataRevertMessage;
mapping(bytes32=>uint) calldataInvocations;
mapping(bytes4=>bytes4) methodIdMocks;
mapping(bytes4=> MockType) methodIdMockTypes;
mapping(bytes4=>bytes) methodIdExpectations;
mapping(bytes4=>string) methodIdRevertMessages;
mapping(bytes32=>uint) methodIdInvocations;
MockType fallbackMockType;
bytes fallbackExpectation = DEFAULT_FALLBACK_VALUE;
string fallbackRevertMessage;
uint invocations;
uint resetCount;
constructor() public{
calldataMocks[MOCKS_LIST_START] = MOCKS_LIST_END;
methodIdMocks[SENTINEL_ANY_MOCKS] = SENTINEL_ANY_MOCKS;
}
functiontrackCalldataMock(bytesmemory call) private{
bytes32 callHash =keccak256(call);
if (calldataMocks[callHash].length==0) {
calldataMocks[callHash] = calldataMocks[MOCKS_LIST_START];
calldataMocks[MOCKS_LIST_START] = call;
}
}
functiontrackMethodIdMock(bytes4 methodId) private{
if (methodIdMocks[methodId] ==0x0) {
methodIdMocks[methodId] = methodIdMocks[SENTINEL_ANY_MOCKS];
methodIdMocks[SENTINEL_ANY_MOCKS] = methodId;
}
}
function_givenAnyReturn(bytesmemory response) internal{
fallbackMockType = MockType.Return;
fallbackExpectation = response;
}
functiongivenAnyReturn(bytescalldata response) overrideexternal{
_givenAnyReturn(response);
}
functiongivenAnyReturnBool(bool response) overrideexternal{
uint flag = response ? 1 : 0;
_givenAnyReturn(uintToBytes(flag));
}
functiongivenAnyReturnUint(uint response) overrideexternal{
_givenAnyReturn(uintToBytes(response));
}
functiongivenAnyReturnAddress(address response) overrideexternal{
_givenAnyReturn(uintToBytes(uint(response)));
}
functiongivenAnyRevert() overrideexternal{
fallbackMockType = MockType.Revert;
fallbackRevertMessage ="";
}
functiongivenAnyRevertWithMessage(stringcalldata message) overrideexternal{
fallbackMockType = MockType.Revert;
fallbackRevertMessage = message;
}
functiongivenAnyRunOutOfGas() overrideexternal{
fallbackMockType = MockType.OutOfGas;
}
function_givenCalldataReturn(bytesmemory call, bytesmemory response) private{
calldataMockTypes[call] = MockType.Return;
calldataExpectations[call] = response;
trackCalldataMock(call);
}
functiongivenCalldataReturn(bytescalldata call, bytescalldata response) overrideexternal{
_givenCalldataReturn(call, response);
}
functiongivenCalldataReturnBool(bytescalldata call, bool response) overrideexternal{
uint flag = response ? 1 : 0;
_givenCalldataReturn(call, uintToBytes(flag));
}
functiongivenCalldataReturnUint(bytescalldata call, uint response) overrideexternal{
_givenCalldataReturn(call, uintToBytes(response));
}
functiongivenCalldataReturnAddress(bytescalldata call, address response) overrideexternal{
_givenCalldataReturn(call, uintToBytes(uint(response)));
}
function_givenMethodReturn(bytesmemory call, bytesmemory response) private{
bytes4 method = bytesToBytes4(call);
methodIdMockTypes[method] = MockType.Return;
methodIdExpectations[method] = response;
trackMethodIdMock(method);
}
functiongivenMethodReturn(bytescalldata call, bytescalldata response) overrideexternal{
_givenMethodReturn(call, response);
}
functiongivenMethodReturnBool(bytescalldata call, bool response) overrideexternal{
uint flag = response ? 1 : 0;
_givenMethodReturn(call, uintToBytes(flag));
}
functiongivenMethodReturnUint(bytescalldata call, uint response) overrideexternal{
_givenMethodReturn(call, uintToBytes(response));
}
functiongivenMethodReturnAddress(bytescalldata call, address response) overrideexternal{
_givenMethodReturn(call, uintToBytes(uint(response)));
}
functiongivenCalldataRevert(bytescalldata call) overrideexternal{
calldataMockTypes[call] = MockType.Revert;
calldataRevertMessage[call] ="";
trackCalldataMock(call);
}
functiongivenMethodRevert(bytescalldata call) overrideexternal{
bytes4 method = bytesToBytes4(call);
methodIdMockTypes[method] = MockType.Revert;
trackMethodIdMock(method);
}
functiongivenCalldataRevertWithMessage(bytescalldata call, stringcalldata message) overrideexternal{
calldataMockTypes[call] = MockType.Revert;
calldataRevertMessage[call] = message;
trackCalldataMock(call);
}
functiongivenMethodRevertWithMessage(bytescalldata call, stringcalldata message) overrideexternal{
bytes4 method = bytesToBytes4(call);
methodIdMockTypes[method] = MockType.Revert;
methodIdRevertMessages[method] = message;
trackMethodIdMock(method);
}
functiongivenCalldataRunOutOfGas(bytescalldata call) overrideexternal{
calldataMockTypes[call] = MockType.OutOfGas;
trackCalldataMock(call);
}
functiongivenMethodRunOutOfGas(bytescalldata call) overrideexternal{
bytes4 method = bytesToBytes4(call);
methodIdMockTypes[method] = MockType.OutOfGas;
trackMethodIdMock(method);
}
functioninvocationCount() overrideexternalreturns (uint) {
return invocations;
}
functioninvocationCountForMethod(bytescalldata call) overrideexternalreturns (uint) {
bytes4 method = bytesToBytes4(call);
return methodIdInvocations[keccak256(abi.encodePacked(resetCount, method))];
}
functioninvocationCountForCalldata(bytescalldata call) overrideexternalreturns (uint) {
return calldataInvocations[keccak256(abi.encodePacked(resetCount, call))];
}
functionreset() overrideexternal{
// Reset all exact calldataMocksbytesmemory nextMock = calldataMocks[MOCKS_LIST_START];
bytes32 mockHash =keccak256(nextMock);
// We cannot compary byteswhile(mockHash != MOCKS_LIST_END_HASH) {
// Reset all mock maps
calldataMockTypes[nextMock] = MockType.Return;
calldataExpectations[nextMock] =hex"";
calldataRevertMessage[nextMock] ="";
// Set next mock to remove
nextMock = calldataMocks[mockHash];
// Remove from linked list
calldataMocks[mockHash] ="";
// Update mock hash
mockHash =keccak256(nextMock);
}
// Clear list
calldataMocks[MOCKS_LIST_START] = MOCKS_LIST_END;
// Reset all any calldataMocksbytes4 nextAnyMock = methodIdMocks[SENTINEL_ANY_MOCKS];
while(nextAnyMock != SENTINEL_ANY_MOCKS) {
bytes4 currentAnyMock = nextAnyMock;
methodIdMockTypes[currentAnyMock] = MockType.Return;
methodIdExpectations[currentAnyMock] =hex"";
methodIdRevertMessages[currentAnyMock] ="";
nextAnyMock = methodIdMocks[currentAnyMock];
// Remove from linked list
methodIdMocks[currentAnyMock] =0x0;
}
// Clear list
methodIdMocks[SENTINEL_ANY_MOCKS] = SENTINEL_ANY_MOCKS;
fallbackExpectation = DEFAULT_FALLBACK_VALUE;
fallbackMockType = MockType.Return;
invocations =0;
resetCount +=1;
}
functionuseAllGas() private{
while(true) {
bool s;
assembly {
//expensive call to EC multiply contract
s :=call(sub(gas(), 2000), 6, 0, 0x0, 0xc0, 0x0, 0x60)
}
}
}
functionbytesToBytes4(bytesmemory b) privatepurereturns (bytes4) {
bytes4 out;
for (uint i =0; i <4; i++) {
out |=bytes4(b[i] &0xFF) >> (i *8);
}
return out;
}
functionuintToBytes(uint256 x) privatepurereturns (bytesmemory b) {
b =newbytes(32);
assembly { mstore(add(b, 32), x) }
}
functionupdateInvocationCount(bytes4 methodId, bytesmemory originalMsgData) public{
require(msg.sender==address(this), "Can only be called from the contract itself");
invocations +=1;
methodIdInvocations[keccak256(abi.encodePacked(resetCount, methodId))] +=1;
calldataInvocations[keccak256(abi.encodePacked(resetCount, originalMsgData))] +=1;
}
fallback () payableexternal{
bytes4 methodId;
assembly {
methodId :=calldataload(0)
}
// First, check exact matching overridesif (calldataMockTypes[msg.data] == MockType.Revert) {
revert(calldataRevertMessage[msg.data]);
}
if (calldataMockTypes[msg.data] == MockType.OutOfGas) {
useAllGas();
}
bytesmemory result = calldataExpectations[msg.data];
// Then check method Id overridesif (result.length==0) {
if (methodIdMockTypes[methodId] == MockType.Revert) {
revert(methodIdRevertMessages[methodId]);
}
if (methodIdMockTypes[methodId] == MockType.OutOfGas) {
useAllGas();
}
result = methodIdExpectations[methodId];
}
// Last, use the fallback overrideif (result.length==0) {
if (fallbackMockType == MockType.Revert) {
revert(fallbackRevertMessage);
}
if (fallbackMockType == MockType.OutOfGas) {
useAllGas();
}
result = fallbackExpectation;
}
// Record invocation as separate call so we don't rollback in case we are called with STATICCALL
(, bytesmemory r) =address(this).call{gas: 100000}(abi.encodeWithSignature("updateInvocationCount(bytes4,bytes)", methodId, msg.data));
assert(r.length==0);
assembly {
return(add(0x20, result), mload(result))
}
}
}
Contract Source Code
File 53 of 71: Ownable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/abstractcontractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor () internal{
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
emit OwnershipTransferred(_owner, address(0));
_owner =address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
Contract Source Code
File 54 of 71: OwnableUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../utils/ContextUpgradeable.sol";
import"../proxy/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/abstractcontractOwnableUpgradeableisInitializable, ContextUpgradeable{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/function__Ownable_init() internalinitializer{
__Context_init_unchained();
__Ownable_init_unchained();
}
function__Ownable_init_unchained() internalinitializer{
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
emit OwnershipTransferred(_owner, address(0));
_owner =address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[49] private __gap;
}
Contract Source Code
File 55 of 71: Pausable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/abstractcontractPausableisContext{
/**
* @dev Emitted when the pause is triggered by `account`.
*/eventPaused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/eventUnpaused(address account);
boolprivate _paused;
/**
* @dev Initializes the contract in unpaused state.
*/constructor () internal{
_paused =false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/functionpaused() publicviewvirtualreturns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/modifierwhenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/modifierwhenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/function_pause() internalvirtualwhenNotPaused{
_paused =true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/function_unpause() internalvirtualwhenPaused{
_paused =false;
emit Unpaused(_msgSender());
}
}
Contract Source Code
File 56 of 71: PausableUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./ContextUpgradeable.sol";
import"../proxy/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/abstractcontractPausableUpgradeableisInitializable, ContextUpgradeable{
/**
* @dev Emitted when the pause is triggered by `account`.
*/eventPaused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/eventUnpaused(address account);
boolprivate _paused;
/**
* @dev Initializes the contract in unpaused state.
*/function__Pausable_init() internalinitializer{
__Context_init_unchained();
__Pausable_init_unchained();
}
function__Pausable_init_unchained() internalinitializer{
_paused =false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/functionpaused() publicviewvirtualreturns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/modifierwhenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/modifierwhenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/function_pause() internalvirtualwhenNotPaused{
_paused =true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/function_unpause() internalvirtualwhenPaused{
_paused =false;
emit Unpaused(_msgSender());
}
uint256[49] private __gap;
}
Contract Source Code
File 57 of 71: Pool.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;import"../interfaces/ILiquidityPool.sol";
import"../interfaces/IManager.sol";
import"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import {SafeMathUpgradeableasSafeMath} from"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import {MathUpgradeableasMath} from"@openzeppelin/contracts-upgradeable/math/MathUpgradeable.sol";
import {OwnableUpgradeableasOwnable} from"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {ERC20UpgradeableasERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {IERC20UpgradeableasIERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20UpgradeableasSafeERC20} from"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol";
import {PausableUpgradeableasPausable} from"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
contractPoolisILiquidityPool, Initializable, ERC20, Ownable, Pausable{
usingSafeMathforuint256;
usingSafeERC20forERC20;
ERC20 publicoverride underlyer;
IManager public manager;
// implied: deployableLiquidity = underlyer.balanceOf(this) - withheldLiquidityuint256publicoverride withheldLiquidity;
// fAsset holder -> WithdrawalInfomapping(address=> WithdrawalInfo) publicoverride requestedWithdrawals;
functioninitialize(
ERC20 _underlyer,
IManager _manager,
stringmemory _name,
stringmemory _symbol
) publicinitializer{
require(address(_underlyer) !=address(0), "ZERO_ADDRESS");
require(address(_manager) !=address(0), "ZERO_ADDRESS");
__Context_init_unchained();
__Ownable_init_unchained();
__Pausable_init_unchained();
__ERC20_init_unchained(_name, _symbol);
underlyer = _underlyer;
manager = _manager;
}
functiondecimals() publicviewoverridereturns (uint8) {
return underlyer.decimals();
}
functiondeposit(uint256 amount) externaloverridewhenNotPaused{
_deposit(msg.sender, msg.sender, amount);
}
functiondepositFor(address account, uint256 amount) externaloverridewhenNotPaused{
_deposit(msg.sender, account, amount);
}
/// @dev References the WithdrawalInfo for how much the user is permitted to withdraw/// @dev No withdrawal permitted unless currentCycle >= minCycle/// @dev Decrements withheldLiquidity by the withdrawn amount/// @dev TODO Update rewardsContract with proper accountingfunctionwithdraw(uint256 requestedAmount) externaloverridewhenNotPaused{
require(
requestedAmount <= requestedWithdrawals[msg.sender].amount,
"WITHDRAW_INSUFFICIENT_BALANCE"
);
require(requestedAmount >0, "NO_WITHDRAWAL");
require(underlyer.balanceOf(address(this)) >= requestedAmount, "INSUFFICIENT_POOL_BALANCE");
require(
requestedWithdrawals[msg.sender].minCycle <= manager.getCurrentCycleIndex(),
"INVALID_CYCLE"
);
requestedWithdrawals[msg.sender].amount = requestedWithdrawals[msg.sender].amount.sub(
requestedAmount
);
if (requestedWithdrawals[msg.sender].amount ==0) {
delete requestedWithdrawals[msg.sender];
}
withheldLiquidity = withheldLiquidity.sub(requestedAmount);
_burn(msg.sender, requestedAmount);
underlyer.safeTransfer(msg.sender, requestedAmount);
}
/// @dev Adjusts the withheldLiquidity as necessary/// @dev Updates the WithdrawalInfo for when a user can withdraw and for what requested amountfunctionrequestWithdrawal(uint256 amount) externaloverride{
require(amount >0, "INVALID_AMOUNT");
require(amount <= balanceOf(msg.sender), "INSUFFICIENT_BALANCE");
//adjust withheld liquidity by removing the original withheld amount and adding the new amount
withheldLiquidity = withheldLiquidity.sub(requestedWithdrawals[msg.sender].amount).add(
amount
);
requestedWithdrawals[msg.sender].amount = amount;
if (manager.getRolloverStatus()) {
requestedWithdrawals[msg.sender].minCycle = manager.getCurrentCycleIndex().add(2);
} else {
requestedWithdrawals[msg.sender].minCycle = manager.getCurrentCycleIndex().add(1);
}
}
functionpreTransferAdjustWithheldLiquidity(address sender, uint256 amount) internal{
if (requestedWithdrawals[sender].amount >0) {
//reduce requested withdraw amount by transferred amount;uint256 newRequestedWithdrawl = requestedWithdrawals[sender].amount.sub(
Math.min(amount, requestedWithdrawals[sender].amount)
);
//subtract from global withheld liquidity (reduce) by removing the delta of (requestedAmount - newRequestedAmount)
withheldLiquidity = withheldLiquidity.sub(
requestedWithdrawals[sender].amount.sub(newRequestedWithdrawl)
);
//update the requested withdraw for user
requestedWithdrawals[sender].amount = newRequestedWithdrawl;
//if the withdraw request is 0, empty it outif (requestedWithdrawals[sender].amount ==0) {
delete requestedWithdrawals[sender];
}
}
}
functionapproveManager(uint256 amount) publicoverrideonlyOwner{
uint256 currentAllowance = underlyer.allowance(address(this), address(manager));
if (currentAllowance < amount) {
uint256 delta = amount.sub(currentAllowance);
underlyer.safeIncreaseAllowance(address(manager), delta);
} else {
uint256 delta = currentAllowance.sub(amount);
underlyer.safeDecreaseAllowance(address(manager), delta);
}
}
/// @dev Adjust withheldLiquidity and requestedWithdrawal if sender does not have sufficient unlocked balance for the transferfunctiontransfer(address recipient, uint256 amount)
publicoverridewhenNotPausedreturns (bool)
{
preTransferAdjustWithheldLiquidity(msg.sender, amount);
returnsuper.transfer(recipient, amount);
}
/// @dev Adjust withheldLiquidity and requestedWithdrawal if sender does not have sufficient unlocked balance for the transferfunctiontransferFrom(address sender,
address recipient,
uint256 amount
) publicoverridewhenNotPausedreturns (bool) {
preTransferAdjustWithheldLiquidity(sender, amount);
returnsuper.transferFrom(sender, recipient, amount);
}
functionpause() externaloverrideonlyOwner{
_pause();
}
functionunpause() externaloverrideonlyOwner{
_unpause();
}
function_deposit(address fromAccount,
address toAccount,
uint256 amount
) internal{
require(amount >0, "INVALID_AMOUNT");
require(toAccount !=address(0), "INVALID_ADDRESS");
_mint(toAccount, amount);
underlyer.safeTransferFrom(fromAccount, address(this), amount);
}
}
// SPDX-License-Identifier: MITpragmasolidity 0.6.11;import"@openzeppelin/contracts/access/Ownable.sol";
import"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import"@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";
import"@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import"../interfaces/IStaking.sol";
/// @title Tokemak Redeem Contract/// @notice Converts PreToke to Toke/// @dev Can only be used when fromToken has been unpausedcontractRedeemisOwnable{
usingSafeERC20forIERC20;
addresspublicimmutable fromToken;
addresspublicimmutable toToken;
addresspublicimmutable stakingContract;
uint256publicimmutable expirationBlock;
uint256publicimmutable stakingSchedule;
/// @notice Redeem Constructor/// @dev approves max uint256 on creation for the toToken against the staking contract/// @param _fromToken the token users will convert from/// @param _toToken the token users will convert to/// @param _stakingContract the staking contract/// @param _expirationBlock a block number at which the owner can withdraw the full balance of toTokenconstructor(address _fromToken,
address _toToken,
address _stakingContract,
uint256 _expirationBlock,
uint256 _stakingSchedule
) public{
require(_fromToken !=address(0), "INVALID_FROMTOKEN");
require(_toToken !=address(0), "INVALID_TOTOKEN");
require(_stakingContract !=address(0), "INVALID_STAKING");
fromToken = _fromToken;
toToken = _toToken;
stakingContract = _stakingContract;
expirationBlock = _expirationBlock;
stakingSchedule = _stakingSchedule;
//Approve staking contract for toToken to allow for staking within convert()
IERC20(_toToken).safeApprove(_stakingContract, type(uint256).max);
}
/// @notice Allows a holder of fromToken to convert into toToken and simultaneously stake within the stakingContract/// @dev a user must approve this contract in order for it to burnFrom()functionconvert() external{
uint256 fromBal = IERC20(fromToken).balanceOf(msg.sender);
require(fromBal >0, "INSUFFICIENT_BALANCE");
ERC20Burnable(fromToken).burnFrom(msg.sender, fromBal);
IStaking(stakingContract).depositFor(msg.sender, fromBal, stakingSchedule);
}
/// @notice Allows the claim on the toToken balance after the expiration has passed/// @dev callable only by ownerfunctionrecoupRemaining() externalonlyOwner{
require(block.number>= expirationBlock, "EXPIRATION_NOT_PASSED");
uint256 bal = IERC20(toToken).balanceOf(address(this));
IERC20(toToken).safeTransfer(msg.sender, bal);
}
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/librarySafeCast{
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/functiontoUint128(uint256 value) internalpurereturns (uint128) {
require(value <2**128, "SafeCast: value doesn\'t fit in 128 bits");
returnuint128(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/functiontoUint64(uint256 value) internalpurereturns (uint64) {
require(value <2**64, "SafeCast: value doesn\'t fit in 64 bits");
returnuint64(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/functiontoUint32(uint256 value) internalpurereturns (uint32) {
require(value <2**32, "SafeCast: value doesn\'t fit in 32 bits");
returnuint32(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/functiontoUint16(uint256 value) internalpurereturns (uint16) {
require(value <2**16, "SafeCast: value doesn\'t fit in 16 bits");
returnuint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*/functiontoUint8(uint256 value) internalpurereturns (uint8) {
require(value <2**8, "SafeCast: value doesn\'t fit in 8 bits");
returnuint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/functiontoUint256(int256 value) internalpurereturns (uint256) {
require(value >=0, "SafeCast: value must be positive");
returnuint256(value);
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/functiontoInt128(int256 value) internalpurereturns (int128) {
require(value >=-2**127&& value <2**127, "SafeCast: value doesn\'t fit in 128 bits");
returnint128(value);
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/functiontoInt64(int256 value) internalpurereturns (int64) {
require(value >=-2**63&& value <2**63, "SafeCast: value doesn\'t fit in 64 bits");
returnint64(value);
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/functiontoInt32(int256 value) internalpurereturns (int32) {
require(value >=-2**31&& value <2**31, "SafeCast: value doesn\'t fit in 32 bits");
returnint32(value);
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/functiontoInt16(int256 value) internalpurereturns (int16) {
require(value >=-2**15&& value <2**15, "SafeCast: value doesn\'t fit in 16 bits");
returnint16(value);
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*
* _Available since v3.1._
*/functiontoInt8(int256 value) internalpurereturns (int8) {
require(value >=-2**7&& value <2**7, "SafeCast: value doesn\'t fit in 8 bits");
returnint8(value);
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/functiontoInt256(uint256 value) internalpurereturns (int256) {
require(value <2**255, "SafeCast: value doesn't fit in an int256");
returnint256(value);
}
}
Contract Source Code
File 62 of 71: SafeERC20.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./IERC20.sol";
import"../../math/SafeMath.sol";
import"../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/librarySafeERC20{
usingSafeMathforuint256;
usingAddressforaddress;
functionsafeTransfer(IERC20 token, address to, uint256 value) internal{
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
functionsafeTransferFrom(IERC20 token, addressfrom, address to, uint256 value) internal{
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/functionsafeApprove(IERC20 token, address spender, uint256 value) internal{
// safeApprove should only be called when setting an initial allowance,// or when resetting it to zero. To increase and decrease it, use// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'// solhint-disable-next-line max-line-lengthrequire((value ==0) || (token.allowance(address(this), spender) ==0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
functionsafeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal{
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
functionsafeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal{
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/function_callOptionalReturn(IERC20 token, bytesmemory data) private{
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that// the target address contains contract code and also asserts for success in the low-level call.bytesmemory returndata =address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length>0) { // Return data is optional// solhint-disable-next-line max-line-lengthrequire(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
Contract Source Code
File 63 of 71: SafeERC20Upgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./IERC20Upgradeable.sol";
import"../../math/SafeMathUpgradeable.sol";
import"../../utils/AddressUpgradeable.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/librarySafeERC20Upgradeable{
usingSafeMathUpgradeableforuint256;
usingAddressUpgradeableforaddress;
functionsafeTransfer(IERC20Upgradeable token, address to, uint256 value) internal{
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
functionsafeTransferFrom(IERC20Upgradeable token, addressfrom, address to, uint256 value) internal{
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/functionsafeApprove(IERC20Upgradeable token, address spender, uint256 value) internal{
// safeApprove should only be called when setting an initial allowance,// or when resetting it to zero. To increase and decrease it, use// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'// solhint-disable-next-line max-line-lengthrequire((value ==0) || (token.allowance(address(this), spender) ==0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
functionsafeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal{
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
functionsafeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal{
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/function_callOptionalReturn(IERC20Upgradeable token, bytesmemory data) private{
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that// the target address contains contract code and also asserts for success in the low-level call.bytesmemory returndata =address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length>0) { // Return data is optional// solhint-disable-next-line max-line-lengthrequire(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
Contract Source Code
File 64 of 71: SafeMath.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryAdd(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontrySub(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryMul(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryDiv(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryMod(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
if (a ==0) return0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a % b;
}
}
Contract Source Code
File 65 of 71: SafeMathUpgradeable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMathUpgradeable{
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryAdd(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontrySub(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryMul(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryDiv(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryMod(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
if (a ==0) return0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a % b;
}
}