Skip to content

Commit 0cc0363

Browse files
committed
Introduce UxGate extension WIP
1 parent d60cbb8 commit 0cc0363

3 files changed

Lines changed: 406 additions & 0 deletions

File tree

contracts/extensions/UxGate.sol

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
This file is part of The Colony Network.
3+
4+
The Colony Network is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
The Colony Network is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with The Colony Network. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
pragma solidity 0.7.3;
19+
pragma experimental ABIEncoderV2;
20+
21+
import "./../../lib/dappsys/erc20.sol";
22+
import "./../colonyNetwork/IColonyNetwork.sol";
23+
import "./ColonyExtensionMeta.sol";
24+
25+
// ignore-file-swc-108
26+
27+
28+
contract UxGate is ColonyExtensionMeta {
29+
30+
// Constants
31+
32+
// Events
33+
34+
event StakeSubmitted(bytes32 indexed stakeType, address indexed staker);
35+
36+
// Data structures
37+
38+
struct Stake {
39+
bytes32 stakeType;
40+
address staker;
41+
uint256 amount;
42+
uint256 cancelledAt;
43+
}
44+
45+
// Storage
46+
47+
address colonyNetworkAddress;
48+
49+
// Parameters keyed by stake type
50+
mapping (bytes32 => uint256) stakeFractions;
51+
mapping (bytes32 => uint256) securityDelays;
52+
53+
uint256 numStakes;
54+
mapping (uint256 => Stake) stakes;
55+
56+
// Modifiers
57+
58+
modifier onlyRootArchitect() {
59+
require(colony.hasUserRole(msgSender(), 1, ColonyDataTypes.ColonyRole.Architecture), "ux-gate-caller-not-root-architect");
60+
_;
61+
}
62+
63+
// Overrides
64+
65+
/// @notice Returns the identifier of the extension
66+
function identifier() public override pure returns (bytes32) {
67+
return keccak256("UxGate");
68+
}
69+
70+
/// @notice Returns the version of the extension
71+
function version() public override pure returns (uint256) {
72+
return 1;
73+
}
74+
75+
/// @notice Configures the extension
76+
/// @param _colony The colony in which the extension holds permissions
77+
function install(address _colony) public override auth {
78+
require(address(colony) == address(0x0), "extension-already-installed");
79+
80+
colony = IColony(_colony);
81+
colonyNetworkAddress = colony.getColonyNetwork();
82+
}
83+
84+
/// @notice Called when upgrading the extension
85+
function finishUpgrade() public override auth {}
86+
87+
/// @notice Called when deprecating (or undeprecating) the extension
88+
function deprecate(bool _deprecated) public override auth {
89+
deprecated = _deprecated;
90+
}
91+
92+
/// @notice Called when uninstalling the extension
93+
function uninstall() public override auth {
94+
selfdestruct(address(uint160(address(colony))));
95+
}
96+
97+
// Public
98+
99+
function setStakeFraction(bytes32 _stakeType, uint256 _stakeFraction) public onlyRootArchitect {
100+
stakeFractions[_stakeType] = _stakeFraction;
101+
}
102+
103+
function setSecurityDelay(bytes32 _stakeType, uint256 securityDelay) public onlyRootArchitect {
104+
securityDelays[_stakeType] = securityDelay;
105+
}
106+
107+
function submitStake(
108+
bytes32 _stakeType,
109+
bytes memory _colonyKey,
110+
bytes memory _colonyValue,
111+
uint256 _colonyBranchMask,
112+
bytes32[] memory _colonySiblings,
113+
bytes memory _userKey,
114+
bytes memory _userValue,
115+
uint256 _userBranchMask,
116+
bytes32[] memory _userSiblings
117+
)
118+
public
119+
notDeprecated
120+
{
121+
bytes32 rootHash = IColonyNetwork(colonyNetworkAddress).getReputationRootHash();
122+
uint256 rootSkillId = colony.getDomain(1).skillId;
123+
124+
uint256 colonyReputation = checkReputation(rootHash, rootSkillId, address(0x0), _colonyKey, _colonyValue, _colonyBranchMask, _colonySiblings);
125+
uint256 userReputation = checkReputation(rootHash, rootSkillId, msgSender(), _userKey, _userValue, _userBranchMask, _userSiblings);
126+
127+
uint256 requiredStake = getRequiredReputation(_stakeType, colonyReputation);
128+
require(userReputation >= requiredStake, "ux-gate-insufficient-rep");
129+
130+
stakes[++numStakes] = Stake({
131+
staker: msgSender(),
132+
stakeType: _stakeType,
133+
amount: requiredStake,
134+
cancelledAt: UINT256_MAX
135+
});
136+
137+
colony.obligateStake(msgSender(), 1, requiredStake);
138+
139+
emit StakeSubmitted(_stakeType, msgSender());
140+
}
141+
142+
function cancelStake() public {}
143+
144+
function reclaimStake() public {}
145+
146+
function slashStake() public {}
147+
148+
// View
149+
150+
function getNumStakes() external view returns (uint256) {
151+
return numStakes;
152+
}
153+
154+
function getStakeFraction(bytes32 _stakeType) external view returns (uint256) {
155+
return stakeFractions[_stakeType];
156+
}
157+
158+
function getSecurityDelay(bytes32 _stakeType) external view returns (uint256) {
159+
return securityDelays[_stakeType];
160+
}
161+
162+
function getStake(uint256 _id) external view returns (Stake memory stake) {
163+
return stakes[_id];
164+
}
165+
166+
// Internal
167+
168+
function getRequiredReputation(bytes32 _stakeType, uint256 _colonyRep) internal view returns (uint256) {
169+
uint256 stakeFraction = stakeFractions[_stakeType] > 0 ? stakeFractions[_stakeType] : WAD;
170+
return wmul(_colonyRep, stakeFraction);
171+
}
172+
}

migrations/9_setup_extensions.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const VotingReputation = artifacts.require("./VotingReputation");
1515
const VotingReputationMisalignedRecovery = artifacts.require("./VotingReputationMisalignedRecovery");
1616
const TokenSupplier = artifacts.require("./TokenSupplier");
1717
const Whitelist = artifacts.require("./Whitelist");
18+
const UxGate = artifacts.require("./UxGate");
1819

1920
const Resolver = artifacts.require("./Resolver");
2021
const EtherRouter = artifacts.require("./EtherRouter");
@@ -53,4 +54,5 @@ module.exports = async function (deployer, network, accounts) {
5354
await addExtension(colonyNetwork, "TokenSupplier", "TokenSupplier", [TokenSupplier]);
5455
await addExtension(colonyNetwork, "IVotingReputation", "VotingReputation", [VotingReputation, VotingReputationMisalignedRecovery]);
5556
await addExtension(colonyNetwork, "Whitelist", "Whitelist", [Whitelist]);
57+
await addExtension(colonyNetwork, "UxGate", "UxGate", [UxGate]);
5658
};

0 commit comments

Comments
 (0)