ShareholdersAgreement
Contract template of Shareholders Agreement
Contract template of Shareholders Agreement
Name
ShareholdersAgreement
Address
Dependent Contract
IShareholdersAgreement, , , ,
// SPDX-License-Identifier: UNLICENSED
/* *
* Copyright (c) 2021-2023 LI LI @ JINGTIAN & GONGCHENG.
*
* This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
* can be obtained at:
* [https://github.com/paul-lee-attorney/comboox]
*
* THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
* EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
*
* YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
* OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
* MORE NODES THAT ARE OUT OF YOUR CONTROL.
* */
pragma solidity ^0.8.8;
import "./IShareholdersAgreement.sol";
import "../../common/components/SigPage.sol";
contract ShareholdersAgreement is IShareholdersAgreement, SigPage {
using EnumerableSet for EnumerableSet.UintSet;
TermsRepo private _terms;
RulesRepo private _rules;
//####################
//## modifier ##
//####################
modifier titleExist(uint256 title) {
require(
hasTitle(title),
"SHA.mf.TE: title not exist"
);
_;
}
//##################
//## Write I/O ##
//##################
function createTerm(uint title, uint version)
external
onlyGC
{
address gc = msg.sender;
uint typeOfDoc = title > 3 ? 21 + title : 22 + title;
bytes32 snOfDoc = bytes32((typeOfDoc << 224) + uint224(version << 192));
DocsRepo.Doc memory doc = _rc.createDoc(snOfDoc, gc);
IAccessControl(doc.body).init(
address(this),
address(this),
address(_rc),
address(_gk)
);
IAccessControl(doc.body).setRoleAdmin(bytes32("Attorneys"), gc);
_terms.terms[title] = doc.body;
_terms.seqList.add(title);
}
function removeTerm(uint title) external onlyAttorney {
if (_terms.seqList.remove(title)) {
delete _terms.terms[title];
}
}
// ==== Rules ====
function addRule(bytes32 rule) external onlyAttorney {
_addRule(rule);
}
function _addRule(bytes32 rule) private {
uint seqOfRule = uint16(uint(rule) >> 240);
_rules.rules[seqOfRule] = rule;
_rules.seqList.add(seqOfRule);
}
function removeRule(uint256 seq) external onlyAttorney {
if (_rules.seqList.remove(seq)) {
delete _rules.rules[seq];
}
}
function initDefaultRules() external onlyDK {
bytes32[] memory rules = new bytes32[](15);
// DefualtGovernanceRule
rules[0] = bytes32(uint(0x000000000003e800000d0503e8003213880500241388000000000000140101f4));
// DefaultVotingRules
rules[1] = bytes32(uint(0x00010c010100001a0b000001000f08070e010100000000000000000000000000));
rules[2] = bytes32(uint(0x00020c020100001388000100010f08070e010107000000000000000000000000));
rules[3] = bytes32(uint(0x00030c030100000000000101000008070e010107000000000000000000000000));
rules[4] = bytes32(uint(0x00040c040100001a0b000001000f08070e010100000000000000000000000000));
rules[5] = bytes32(uint(0x00050c050100001388000100010f08070e010100000000000000000000000000));
rules[6] = bytes32(uint(0x00060c060100001a0b000001000f08070e010100000000000000000000000000));
rules[7] = bytes32(uint(0x00070c070100001a0b000001000f08070e010100000000000000000000000000));
rules[8] = bytes32(uint(0x00080c080100001a0b000001000000001d010100000000000000000000000000));
rules[9] = bytes32(uint(0x00090c090100001388010000000000001d010100000000000000000000000000));
rules[10] = bytes32(uint(0x000a0c0a0100001a0b010000000000001d010100000000000000000000000000));
rules[11] = bytes32(uint(0x000b0c0b02138800000100000000000009010100000000000000000000000000));
rules[12] = bytes32(uint(0x000c0c0c021a0b00000100000000000009010100000000000000000000000000));
// DefaultFirstRefusalRules
rules[13] = bytes32(uint(0x0200020101010100000000000000000000000000000000000000000000000000));
rules[14] = bytes32(uint(0x0201020202010100000000000000000000000000000000000000000000000000));
uint len = 15;
while (len > 0) {
_addRule(rules[len - 1]);
len--;
}
}
// ==== Finalize SHA ====
function finalizeSHA() external {
uint[] memory titles = getTitles();
uint len = titles.length;
while (len > 0) {
IAccessControl(_terms.terms[titles[len-1]]).lockContents();
len --;
}
lockContents();
}
//################
//## Read ##
//################
// ==== Terms ====
function hasTitle(uint256 title) public view returns (bool) {
return _terms.seqList.contains(title);
}
function qtyOfTerms() external view returns (uint256) {
return _terms.seqList.length();
}
function getTitles() public view returns (uint256[] memory) {
return _terms.seqList.values();
}
function getTerm(uint256 title) external view titleExist(title) returns (address) {
return _terms.terms[title];
}
// ==== Rules ====
function hasRule(uint256 seq) external view returns (bool) {
return _rules.seqList.contains(seq);
}
function qtyOfRules() external view returns (uint256) {
return _rules.seqList.length();
}
function getRules() external view returns (uint256[] memory) {
return _rules.seqList.values();
}
function getRule(uint256 seq) external view returns (bytes32) {
return _rules.rules[seq];
}
}
// SPDX-License-Identifier: UNLICENSED
/* *
* Copyright (c) 2021-2023 LI LI @ JINGTIAN & GONGCHENG.
*
* This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
* can be obtained at:
* [https://github.com/paul-lee-attorney/comboox]
*
* THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
* EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
*
* YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
* OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
* MORE NODES THAT ARE OUT OF YOUR CONTROL.
* */
pragma solidity ^0.8.8;
import "../../common/components/ISigPage.sol";
import "../../../lib/EnumerableSet.sol";
import "../../../lib/DocsRepo.sol";
interface IShareholdersAgreement is ISigPage {
enum TitleOfTerm {
ZeroPoint,
AntiDilution, // 1
LockUp, // 2
DragAlong, // 3
TagAlong, // 4
Options // 5
}
// ==== Rules ========
/*
| Seq | Type | Abb | Description |
| 0 | GovernanceRule | GR | Board Constitution and General Rules of GM |
| 1 | VotingRuleOfGM | CI | VR for Capital Increase |
| 2 | | SText | VR for External Share Transfer |
| 3 | | STint | VR for Internal Share Transfer |
| 4 | | 1+3 | VR for CI & STint |
| 5 | | 2+3 | VR for SText & STint |
| 6 | | 1+2+3 | VR for CI & SText & STint |
| 7 | | 1+2 | VR for CI & SText |
| 8 | | SHA | VR for Update SHA |
| 9 | | O-Issue-GM | VR for Ordinary Issues of GeneralMeeting |
| 10 | | S-Issue-GM | VR for Special Issues Of GeneralMeeting |
| 11 | VotingRuleOfBoard | CI | VR for Capital Increase |
| 12 | | SText | VR for External Share Transfer |
| 13 | | STint | VR for Internal Share Transfer |
| 14 | | 1+3 | VR for CI & STint |
| 15 | | 2+3 | VR for SText & STint |
| 16 | | 1+2+3 | VR for CI & SText & STint |
| 17 | | 1+2 | VR for CI & SText |
| 18 | | SHA | VR for Update SHA |
| 19 | | O-Issue-B | VR for Ordinary Issues Of Board |
| 20 | | S-Issue-B | VR for Special Issues Of Board |
| 21 | UnilateralDecision| UniDecPower | UnilateralDicisionPowerWithoutVoting |
...
| 256 | PositionAllocateRule | PA Rule | Management Positions' Allocation Rules |
...
| 512 | FirstRefusalRule | FR for CI...| FR rule for Investment Deal |
...
| 768 | GroupUpdateOrder | GroupUpdate | Grouping Members as per their relationship |
...
| 1024 | ListingRule | ListingRule | Listing Rule for Share Issue & Transfer |
...
*/
struct TermsRepo {
// title => body
mapping(uint256 => address) terms;
EnumerableSet.UintSet seqList;
}
struct RulesRepo {
// seq => rule
mapping(uint256 => bytes32) rules;
EnumerableSet.UintSet seqList;
}
//##################
//## Write I/O ##
//##################
function createTerm(uint typeOfDoc, uint version) external;
function removeTerm(uint typeOfDoc) external;
function addRule(bytes32 rule) external;
function removeRule(uint256 seq) external;
function initDefaultRules() external;
function finalizeSHA() external;
//################
//## Read ##
//################
// ==== Terms ====
function hasTitle(uint256 title) external view returns (bool);
function qtyOfTerms() external view returns (uint256);
function getTitles() external view returns (uint256[] memory);
function getTerm(uint256 title) external view returns (address);
// ==== Rules ====
function hasRule(uint256 seq) external view returns (bool);
function qtyOfRules() external view returns (uint256);
function getRules() external view returns (uint256[] memory);
function getRule(uint256 seq) external view returns (bytes32);
}