@venusprotocol/governance-contracts 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,234 @@
1
+ pragma solidity ^0.5.16;
2
+ pragma experimental ABIEncoderV2;
3
+
4
+ contract GovernorBravoEvents {
5
+ /// @notice An event emitted when a new proposal is created
6
+ event ProposalCreated(
7
+ uint id,
8
+ address proposer,
9
+ address[] targets,
10
+ uint[] values,
11
+ string[] signatures,
12
+ bytes[] calldatas,
13
+ uint startBlock,
14
+ uint endBlock,
15
+ string description,
16
+ uint8 proposalType
17
+ );
18
+
19
+ /// @notice An event emitted when a vote has been cast on a proposal
20
+ /// @param voter The address which casted a vote
21
+ /// @param proposalId The proposal id which was voted on
22
+ /// @param support Support value for the vote. 0=against, 1=for, 2=abstain
23
+ /// @param votes Number of votes which were cast by the voter
24
+ /// @param reason The reason given for the vote by the voter
25
+ event VoteCast(address indexed voter, uint proposalId, uint8 support, uint votes, string reason);
26
+
27
+ /// @notice An event emitted when a proposal has been canceled
28
+ event ProposalCanceled(uint id);
29
+
30
+ /// @notice An event emitted when a proposal has been queued in the Timelock
31
+ event ProposalQueued(uint id, uint eta);
32
+
33
+ /// @notice An event emitted when a proposal has been executed in the Timelock
34
+ event ProposalExecuted(uint id);
35
+
36
+ /// @notice An event emitted when the voting delay is set
37
+ event VotingDelaySet(uint oldVotingDelay, uint newVotingDelay);
38
+
39
+ /// @notice An event emitted when the voting period is set
40
+ event VotingPeriodSet(uint oldVotingPeriod, uint newVotingPeriod);
41
+
42
+ /// @notice Emitted when implementation is changed
43
+ event NewImplementation(address oldImplementation, address newImplementation);
44
+
45
+ /// @notice Emitted when proposal threshold is set
46
+ event ProposalThresholdSet(uint oldProposalThreshold, uint newProposalThreshold);
47
+
48
+ /// @notice Emitted when pendingAdmin is changed
49
+ event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);
50
+
51
+ /// @notice Emitted when pendingAdmin is accepted, which means admin is updated
52
+ event NewAdmin(address oldAdmin, address newAdmin);
53
+
54
+ /// @notice Emitted when the new guardian address is set
55
+ event NewGuardian(address oldGuardian, address newGuardian);
56
+
57
+ /// @notice Emitted when the maximum number of operations in one proposal is updated
58
+ event ProposalMaxOperationsUpdated(uint oldMaxOperations, uint newMaxOperations);
59
+ }
60
+
61
+ contract GovernorBravoDelegatorStorage {
62
+ /// @notice Administrator for this contract
63
+ address public admin;
64
+
65
+ /// @notice Pending administrator for this contract
66
+ address public pendingAdmin;
67
+
68
+ /// @notice Active brains of Governor
69
+ address public implementation;
70
+ }
71
+
72
+ /**
73
+ * @title Storage for Governor Bravo Delegate
74
+ * @notice For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new
75
+ * contract which implements GovernorBravoDelegateStorageV1 and following the naming convention
76
+ * GovernorBravoDelegateStorageVX.
77
+ */
78
+ contract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {
79
+ /// @notice DEPRECATED The delay before voting on a proposal may take place, once proposed, in blocks
80
+ uint public votingDelay;
81
+
82
+ /// @notice DEPRECATED The duration of voting on a proposal, in blocks
83
+ uint public votingPeriod;
84
+
85
+ /// @notice DEPRECATED The number of votes required in order for a voter to become a proposer
86
+ uint public proposalThreshold;
87
+
88
+ /// @notice Initial proposal id set at become
89
+ uint public initialProposalId;
90
+
91
+ /// @notice The total number of proposals
92
+ uint public proposalCount;
93
+
94
+ /// @notice The address of the Venus Protocol Timelock
95
+ TimelockInterface public timelock;
96
+
97
+ /// @notice The address of the Venus governance token
98
+ XvsVaultInterface public xvsVault;
99
+
100
+ /// @notice The official record of all proposals ever proposed
101
+ mapping(uint => Proposal) public proposals;
102
+
103
+ /// @notice The latest proposal for each proposer
104
+ mapping(address => uint) public latestProposalIds;
105
+
106
+ struct Proposal {
107
+ /// @notice Unique id for looking up a proposal
108
+ uint id;
109
+ /// @notice Creator of the proposal
110
+ address proposer;
111
+ /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
112
+ uint eta;
113
+ /// @notice the ordered list of target addresses for calls to be made
114
+ address[] targets;
115
+ /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
116
+ uint[] values;
117
+ /// @notice The ordered list of function signatures to be called
118
+ string[] signatures;
119
+ /// @notice The ordered list of calldata to be passed to each call
120
+ bytes[] calldatas;
121
+ /// @notice The block at which voting begins: holders must delegate their votes prior to this block
122
+ uint startBlock;
123
+ /// @notice The block at which voting ends: votes must be cast prior to this block
124
+ uint endBlock;
125
+ /// @notice Current number of votes in favor of this proposal
126
+ uint forVotes;
127
+ /// @notice Current number of votes in opposition to this proposal
128
+ uint againstVotes;
129
+ /// @notice Current number of votes for abstaining for this proposal
130
+ uint abstainVotes;
131
+ /// @notice Flag marking whether the proposal has been canceled
132
+ bool canceled;
133
+ /// @notice Flag marking whether the proposal has been executed
134
+ bool executed;
135
+ /// @notice Receipts of ballots for the entire set of voters
136
+ mapping(address => Receipt) receipts;
137
+ /// @notice The type of the proposal
138
+ uint8 proposalType;
139
+ }
140
+
141
+ /// @notice Ballot receipt record for a voter
142
+ struct Receipt {
143
+ /// @notice Whether or not a vote has been cast
144
+ bool hasVoted;
145
+ /// @notice Whether or not the voter supports the proposal or abstains
146
+ uint8 support;
147
+ /// @notice The number of votes the voter had, which were cast
148
+ uint96 votes;
149
+ }
150
+
151
+ /// @notice Possible states that a proposal may be in
152
+ enum ProposalState {
153
+ Pending,
154
+ Active,
155
+ Canceled,
156
+ Defeated,
157
+ Succeeded,
158
+ Queued,
159
+ Expired,
160
+ Executed
161
+ }
162
+
163
+ /// @notice The maximum number of actions that can be included in a proposal
164
+ uint public proposalMaxOperations;
165
+
166
+ /// @notice A privileged role that can cancel any proposal
167
+ address public guardian;
168
+ }
169
+
170
+ contract GovernorBravoDelegateStorageV2 is GovernorBravoDelegateStorageV1 {
171
+ enum ProposalType {
172
+ NORMAL,
173
+ FASTTRACK,
174
+ CRITICAL
175
+ }
176
+
177
+ struct ProposalConfig {
178
+ /// @notice The delay before voting on a proposal may take place, once proposed, in blocks
179
+ uint256 votingDelay;
180
+ /// @notice The duration of voting on a proposal, in blocks
181
+ uint256 votingPeriod;
182
+ /// @notice The number of votes required in order for a voter to become a proposer
183
+ uint256 proposalThreshold;
184
+ }
185
+
186
+ /// @notice mapping containing configuration for each proposal type
187
+ mapping(uint => ProposalConfig) public proposalConfigs;
188
+
189
+ /// @notice mapping containing Timelock addresses for each proposal type
190
+ mapping(uint => TimelockInterface) public proposalTimelocks;
191
+ }
192
+
193
+ interface TimelockInterface {
194
+ function delay() external view returns (uint);
195
+
196
+ function GRACE_PERIOD() external view returns (uint);
197
+
198
+ function acceptAdmin() external;
199
+
200
+ function queuedTransactions(bytes32 hash) external view returns (bool);
201
+
202
+ function queueTransaction(
203
+ address target,
204
+ uint value,
205
+ string calldata signature,
206
+ bytes calldata data,
207
+ uint eta
208
+ ) external returns (bytes32);
209
+
210
+ function cancelTransaction(
211
+ address target,
212
+ uint value,
213
+ string calldata signature,
214
+ bytes calldata data,
215
+ uint eta
216
+ ) external;
217
+
218
+ function executeTransaction(
219
+ address target,
220
+ uint value,
221
+ string calldata signature,
222
+ bytes calldata data,
223
+ uint eta
224
+ ) external payable returns (bytes memory);
225
+ }
226
+
227
+ interface XvsVaultInterface {
228
+ function getPriorVotes(address account, uint blockNumber) external view returns (uint96);
229
+ }
230
+
231
+ interface GovernorAlphaInterface {
232
+ /// @notice The total number of proposals
233
+ function proposalCount() external returns (uint);
234
+ }
@@ -0,0 +1,120 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ pragma solidity 0.5.16;
3
+
4
+ interface IAccessControlManagerV5 {
5
+ /**
6
+ * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
7
+ *
8
+ * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
9
+ * {RoleAdminChanged} not being emitted signaling this.
10
+ *
11
+ */
12
+ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
13
+
14
+ /**
15
+ * @dev Emitted when `account` is granted `role`.
16
+ *
17
+ * `sender` is the account that originated the contract call, an admin role
18
+ * bearer except when using {AccessControl-_setupRole}.
19
+ */
20
+ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
21
+
22
+ /**
23
+ * @dev Emitted when `account` is revoked `role`.
24
+ *
25
+ * `sender` is the account that originated the contract call:
26
+ * - if using `revokeRole`, it is the admin role bearer
27
+ * - if using `renounceRole`, it is the role bearer (i.e. `account`)
28
+ */
29
+ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
30
+
31
+ /**
32
+ * @dev Returns `true` if `account` has been granted `role`.
33
+ */
34
+ function hasRole(bytes32 role, address account) external view returns (bool);
35
+
36
+ /**
37
+ * @dev Returns the admin role that controls `role`. See {grantRole} and
38
+ * {revokeRole}.
39
+ *
40
+ * To change a role's admin, use {AccessControl-_setRoleAdmin}.
41
+ */
42
+ function getRoleAdmin(bytes32 role) external view returns (bytes32);
43
+
44
+ /**
45
+ * @dev Grants `role` to `account`.
46
+ *
47
+ * If `account` had not been already granted `role`, emits a {RoleGranted}
48
+ * event.
49
+ *
50
+ * Requirements:
51
+ *
52
+ * - the caller must have ``role``'s admin role.
53
+ */
54
+ function grantRole(bytes32 role, address account) external;
55
+
56
+ /**
57
+ * @dev Revokes `role` from `account`.
58
+ *
59
+ * If `account` had been granted `role`, emits a {RoleRevoked} event.
60
+ *
61
+ * Requirements:
62
+ *
63
+ * - the caller must have ``role``'s admin role.
64
+ */
65
+ function revokeRole(bytes32 role, address account) external;
66
+
67
+ /**
68
+ * @dev Revokes `role` from the calling account.
69
+ *
70
+ * Roles are often managed via {grantRole} and {revokeRole}: this function's
71
+ * purpose is to provide a mechanism for accounts to lose their privileges
72
+ * if they are compromised (such as when a trusted device is misplaced).
73
+ *
74
+ * If the calling account had been granted `role`, emits a {RoleRevoked}
75
+ * event.
76
+ *
77
+ * Requirements:
78
+ *
79
+ * - the caller must be `account`.
80
+ */
81
+ function renounceRole(bytes32 role, address account) external;
82
+
83
+ /**
84
+ * @notice Gives a function call permission to one single account
85
+ * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE
86
+ * May emit a {RoleGranted} event.
87
+ * @param contractAddress address of contract for which call permissions will be granted
88
+ * @param functionSig signature e.g. "functionName(uint,bool)"
89
+ */
90
+ function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;
91
+
92
+ /**
93
+ * @notice Revokes an account's permission to a particular function call
94
+ * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE
95
+ * May emit a {RoleRevoked} event.
96
+ * @param contractAddress address of contract for which call permissions will be revoked
97
+ * @param functionSig signature e.g. "functionName(uint,bool)"
98
+ */
99
+ function revokeCallPermission(
100
+ address contractAddress,
101
+ string calldata functionSig,
102
+ address accountToRevoke
103
+ ) external;
104
+
105
+ /**
106
+ * @notice Verifies if the given account can call a praticular contract's function
107
+ * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender
108
+ * @param account address (eoa or contract) for which call permissions will be checked
109
+ * @param functionSig signature e.g. "functionName(uint,bool)"
110
+ * @return false if the user account cannot call the particular contract function
111
+ *
112
+ */
113
+ function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);
114
+
115
+ function hasPermission(
116
+ address account,
117
+ address contractAddress,
118
+ string calldata functionSig
119
+ ) external view returns (bool);
120
+ }
@@ -0,0 +1,22 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ pragma solidity 0.8.13;
3
+
4
+ import "@openzeppelin/contracts/access/IAccessControl.sol";
5
+
6
+ interface IAccessControlManagerV8 is IAccessControl {
7
+ function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;
8
+
9
+ function revokeCallPermission(
10
+ address contractAddress,
11
+ string calldata functionSig,
12
+ address accountToRevoke
13
+ ) external;
14
+
15
+ function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);
16
+
17
+ function hasPermission(
18
+ address account,
19
+ address contractAddress,
20
+ string calldata functionSig
21
+ ) external view returns (bool);
22
+ }
@@ -0,0 +1,152 @@
1
+ pragma solidity ^0.5.16;
2
+
3
+ import "../Utils/SafeMath.sol";
4
+
5
+ contract Timelock {
6
+ using SafeMath for uint;
7
+
8
+ event NewAdmin(address indexed newAdmin);
9
+ event NewPendingAdmin(address indexed newPendingAdmin);
10
+ event NewDelay(uint indexed newDelay);
11
+ event CancelTransaction(
12
+ bytes32 indexed txHash,
13
+ address indexed target,
14
+ uint value,
15
+ string signature,
16
+ bytes data,
17
+ uint eta
18
+ );
19
+ event ExecuteTransaction(
20
+ bytes32 indexed txHash,
21
+ address indexed target,
22
+ uint value,
23
+ string signature,
24
+ bytes data,
25
+ uint eta
26
+ );
27
+ event QueueTransaction(
28
+ bytes32 indexed txHash,
29
+ address indexed target,
30
+ uint value,
31
+ string signature,
32
+ bytes data,
33
+ uint eta
34
+ );
35
+
36
+ uint public constant GRACE_PERIOD = 14 days;
37
+ uint public constant MINIMUM_DELAY = 1 hours;
38
+ uint public constant MAXIMUM_DELAY = 30 days;
39
+
40
+ address public admin;
41
+ address public pendingAdmin;
42
+ uint public delay;
43
+
44
+ mapping(bytes32 => bool) public queuedTransactions;
45
+
46
+ constructor(address admin_, uint delay_) public {
47
+ require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay.");
48
+ require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
49
+
50
+ admin = admin_;
51
+ delay = delay_;
52
+ }
53
+
54
+ function() external payable {}
55
+
56
+ function setDelay(uint delay_) public {
57
+ require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
58
+ require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
59
+ require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
60
+ delay = delay_;
61
+
62
+ emit NewDelay(delay);
63
+ }
64
+
65
+ function acceptAdmin() public {
66
+ require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
67
+ admin = msg.sender;
68
+ pendingAdmin = address(0);
69
+
70
+ emit NewAdmin(admin);
71
+ }
72
+
73
+ function setPendingAdmin(address pendingAdmin_) public {
74
+ require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
75
+ pendingAdmin = pendingAdmin_;
76
+
77
+ emit NewPendingAdmin(pendingAdmin);
78
+ }
79
+
80
+ function queueTransaction(
81
+ address target,
82
+ uint value,
83
+ string memory signature,
84
+ bytes memory data,
85
+ uint eta
86
+ ) public returns (bytes32) {
87
+ require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
88
+ require(
89
+ eta >= getBlockTimestamp().add(delay),
90
+ "Timelock::queueTransaction: Estimated execution block must satisfy delay."
91
+ );
92
+
93
+ bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
94
+ queuedTransactions[txHash] = true;
95
+
96
+ emit QueueTransaction(txHash, target, value, signature, data, eta);
97
+ return txHash;
98
+ }
99
+
100
+ function cancelTransaction(
101
+ address target,
102
+ uint value,
103
+ string memory signature,
104
+ bytes memory data,
105
+ uint eta
106
+ ) public {
107
+ require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");
108
+
109
+ bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
110
+ queuedTransactions[txHash] = false;
111
+
112
+ emit CancelTransaction(txHash, target, value, signature, data, eta);
113
+ }
114
+
115
+ function executeTransaction(
116
+ address target,
117
+ uint value,
118
+ string memory signature,
119
+ bytes memory data,
120
+ uint eta
121
+ ) public payable returns (bytes memory) {
122
+ require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");
123
+
124
+ bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
125
+ require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
126
+ require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
127
+ require(getBlockTimestamp() <= eta.add(GRACE_PERIOD), "Timelock::executeTransaction: Transaction is stale.");
128
+
129
+ queuedTransactions[txHash] = false;
130
+
131
+ bytes memory callData;
132
+
133
+ if (bytes(signature).length == 0) {
134
+ callData = data;
135
+ } else {
136
+ callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
137
+ }
138
+
139
+ // solium-disable-next-line security/no-call-value
140
+ (bool success, bytes memory returnData) = target.call.value(value)(callData);
141
+ require(success, "Timelock::executeTransaction: Transaction execution reverted.");
142
+
143
+ emit ExecuteTransaction(txHash, target, value, signature, data, eta);
144
+
145
+ return returnData;
146
+ }
147
+
148
+ function getBlockTimestamp() internal view returns (uint) {
149
+ // solium-disable-next-line security/no-block-members
150
+ return block.timestamp;
151
+ }
152
+ }
@@ -0,0 +1,163 @@
1
+ pragma solidity ^0.5.16;
2
+
3
+ /**
4
+ * @dev Wrappers over Solidity's arithmetic operations with added overflow
5
+ * checks.
6
+ *
7
+ * Arithmetic operations in Solidity wrap on overflow. This can easily result
8
+ * in bugs, because programmers usually assume that an overflow raises an
9
+ * error, which is the standard behavior in high level programming languages.
10
+ * `SafeMath` restores this intuition by reverting the transaction when an
11
+ * operation overflows.
12
+ *
13
+ * Using this library instead of the unchecked operations eliminates an entire
14
+ * class of bugs, so it's recommended to use it always.
15
+ */
16
+ library SafeMath {
17
+ /**
18
+ * @dev Returns the addition of two unsigned integers, reverting on
19
+ * overflow.
20
+ *
21
+ * Counterpart to Solidity's `+` operator.
22
+ *
23
+ * Requirements:
24
+ * - Addition cannot overflow.
25
+ */
26
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
27
+ return add(a, b, "SafeMath: addition overflow");
28
+ }
29
+
30
+ /**
31
+ * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
32
+ * overflow (when the result is negative).
33
+ *
34
+ * Counterpart to Solidity's `-` operator.
35
+ *
36
+ * Requirements:
37
+ * - Subtraction cannot overflow.
38
+ */
39
+ function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
40
+ uint256 c = a + b;
41
+ require(c >= a, errorMessage);
42
+
43
+ return c;
44
+ }
45
+
46
+ /**
47
+ * @dev Returns the subtraction of two unsigned integers, reverting on
48
+ * overflow (when the result is negative).
49
+ *
50
+ * Counterpart to Solidity's `-` operator.
51
+ *
52
+ * Requirements:
53
+ * - Subtraction cannot overflow.
54
+ */
55
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
56
+ return sub(a, b, "SafeMath: subtraction overflow");
57
+ }
58
+
59
+ /**
60
+ * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
61
+ * overflow (when the result is negative).
62
+ *
63
+ * Counterpart to Solidity's `-` operator.
64
+ *
65
+ * Requirements:
66
+ * - Subtraction cannot overflow.
67
+ */
68
+ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
69
+ require(b <= a, errorMessage);
70
+ uint256 c = a - b;
71
+
72
+ return c;
73
+ }
74
+
75
+ /**
76
+ * @dev Returns the multiplication of two unsigned integers, reverting on
77
+ * overflow.
78
+ *
79
+ * Counterpart to Solidity's `*` operator.
80
+ *
81
+ * Requirements:
82
+ * - Multiplication cannot overflow.
83
+ */
84
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
85
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
86
+ // benefit is lost if 'b' is also tested.
87
+ // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
88
+ if (a == 0) {
89
+ return 0;
90
+ }
91
+
92
+ uint256 c = a * b;
93
+ require(c / a == b, "SafeMath: multiplication overflow");
94
+
95
+ return c;
96
+ }
97
+
98
+ /**
99
+ * @dev Returns the integer division of two unsigned integers. Reverts on
100
+ * division by zero. The result is rounded towards zero.
101
+ *
102
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
103
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
104
+ * uses an invalid opcode to revert (consuming all remaining gas).
105
+ *
106
+ * Requirements:
107
+ * - The divisor cannot be zero.
108
+ */
109
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
110
+ return div(a, b, "SafeMath: division by zero");
111
+ }
112
+
113
+ /**
114
+ * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
115
+ * division by zero. The result is rounded towards zero.
116
+ *
117
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
118
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
119
+ * uses an invalid opcode to revert (consuming all remaining gas).
120
+ *
121
+ * Requirements:
122
+ * - The divisor cannot be zero.
123
+ */
124
+ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
125
+ // Solidity only automatically asserts when dividing by 0
126
+ require(b > 0, errorMessage);
127
+ uint256 c = a / b;
128
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
129
+
130
+ return c;
131
+ }
132
+
133
+ /**
134
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
135
+ * Reverts when dividing by zero.
136
+ *
137
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
138
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
139
+ * invalid opcode to revert (consuming all remaining gas).
140
+ *
141
+ * Requirements:
142
+ * - The divisor cannot be zero.
143
+ */
144
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
145
+ return mod(a, b, "SafeMath: modulo by zero");
146
+ }
147
+
148
+ /**
149
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
150
+ * Reverts with custom message when dividing by zero.
151
+ *
152
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
153
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
154
+ * invalid opcode to revert (consuming all remaining gas).
155
+ *
156
+ * Requirements:
157
+ * - The divisor cannot be zero.
158
+ */
159
+ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
160
+ require(b != 0, errorMessage);
161
+ return a % b;
162
+ }
163
+ }