0xfacet-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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9fac7c3c3df979bc789b4b300cf331972a368edb51fd2c8646654564ecd25e81
4
+ data.tar.gz: 696b46279ae0a4b54c26249ae879c4514f80e0720aaeada490874d90bacb7d53
5
+ SHA512:
6
+ metadata.gz: 580db8d5ab28967cc8b3886de2f2bedc53efe5ba83b6c87d2786c08c3e4e716223fc570b9eb84a4f7b346755a67a9552e87f6bbf22da7296028c20f67e7c2659
7
+ data.tar.gz: 6e2f3120f2978f4b9e29c1e80f17bff93380400d956c9b436679ee0abd4a90f9992bdd7e63d97ebecf3d85ea975a7d7a7bcd0b062ab78fdfe0afe47d6eccd415
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 0.0.1 / 2023-11-16
2
+
3
+ * Everything is new. First release
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ CHANGELOG.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ lib/0xfacet/contracts.rb
6
+ lib/0xfacet/contracts/ERC20.rb
7
+ lib/0xfacet/contracts/ERC721.rb
8
+ lib/0xfacet/contracts/EtherBridge.rb
9
+ lib/0xfacet/contracts/EtherBridgeV2.rb
10
+ lib/0xfacet/contracts/EthscriptionERC20Bridge.rb
11
+ lib/0xfacet/contracts/GenerativeERC721.rb
12
+ lib/0xfacet/contracts/OpenEditionERC721.rb
13
+ lib/0xfacet/contracts/PublicMintERC20.rb
14
+ lib/0xfacet/contracts/UnsafeNoApprovalERC20.rb
15
+ lib/0xfacet/contracts/Upgradeable.rb
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # 0xFacet Rubidity O.G. Standard Contracts
2
+
3
+ 0xfacet-contracts - rubidity o.g. standard contracts (incl. ERC20, PublicMintERC20, ERC721, GenerativeERC721, etc.)
4
+
5
+ * home :: [github.com/s6ruby/rubidity.review](https://github.com/s6ruby/rubidity.review)
6
+ * bugs :: [github.com/s6ruby/rubidity.review/issues](https://github.com/s6ruby/rubidity/issues)
7
+ * gem :: [rubygems.org/gems/0xfacet-contracts](https://rubygems.org/gems/0xfacet-contracts)
8
+ * rdoc :: [rubydoc.info/gems/0xfacet-contracts](http://rubydoc.info/gems/0xfacet-contracts)
9
+
10
+
11
+
12
+ ## About
13
+
14
+ What's happening herè?
15
+
16
+ The idea is to look at the facet vm code as-is (that is, NOT suggesting new or alternate syntax and semantics) in the review / commentary
17
+ and start to (re)package / modular-ize
18
+ code in "place holder" gems (waiting for adoption by the founders) such as 0xfacet and 0xfacet-typed and 0xfacet-rubidity.
19
+
20
+ See [Rubidity O.G. (Dumb Contracts) Public Code Review / (More) Tests / Gems & More »](https://github.com/s6ruby/rubidity.review)
21
+
22
+
23
+
24
+
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'hoe'
2
+
3
+ # require './lib/0xfacet/version.rb'
4
+
5
+
6
+ Hoe.spec '0xfacet-contracts' do
7
+
8
+ self.version = '0.0.1'
9
+
10
+ self.summary = '0xfacet-contracts - rubidity o.g. standard contracts (incl. ERC20, PublicMintERC20, ERC721, GenerativeERC721, etc.)'
11
+ self.description = summary
12
+
13
+ self.urls = { home: 'https://github.com/s6ruby/rubidity.review' }
14
+
15
+ self.author = 'Gerald Bauer'
16
+ self.email = 'gerald.bauer@gmail.com'
17
+
18
+ # switch extension to .markdown for gihub formatting
19
+ self.readme_file = 'README.md'
20
+ self.history_file = 'CHANGELOG.md'
21
+
22
+ self.extra_deps = [
23
+ ['0xfacet-rubidity', '>= 0.0.1'],
24
+ ]
25
+
26
+
27
+ self.licenses = ['Public Domain']
28
+
29
+ self.spec_extras = {
30
+ required_ruby_version: '>= 2.3'
31
+ }
32
+ end
@@ -0,0 +1,76 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ contract :ERC20, abstract: true do
4
+ event :Transfer, { from: :address, to: :address, amount: :uint256 }
5
+ event :Approval, { owner: :address, spender: :address, amount: :uint256 }
6
+
7
+ string :public, :name
8
+ string :public, :symbol
9
+ uint8 :public, :decimals
10
+
11
+ uint256 :public, :totalSupply
12
+
13
+ mapping ({ address: :uint256 }), :public, :balanceOf
14
+ mapping ({ address: mapping(address: :uint256) }), :public, :allowance
15
+
16
+ constructor(name: :string, symbol: :string, decimals: :uint8) {
17
+ s.name = name
18
+ s.symbol = symbol
19
+ s.decimals = decimals
20
+ }
21
+
22
+ function :approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool do
23
+ s.allowance[msg.sender][spender] = amount
24
+
25
+ emit :Approval, owner: msg.sender, spender: spender, amount: amount
26
+
27
+ return true
28
+ end
29
+
30
+ function :transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool do
31
+ require(s.balanceOf[msg.sender] >= amount, "Insufficient balance")
32
+
33
+ s.balanceOf[msg.sender] -= amount
34
+ s.balanceOf[to] += amount
35
+
36
+ emit :Transfer, from: msg.sender, to: to, amount: amount
37
+
38
+ return true
39
+ end
40
+
41
+ function :transferFrom, {
42
+ from: :address,
43
+ to: :address,
44
+ amount: :uint256
45
+ }, :public, :virtual, returns: :bool do
46
+ allowed = s.allowance[from][msg.sender]
47
+
48
+ require(s.balanceOf[from] >= amount, "Insufficient balance")
49
+ require(allowed >= amount, "Insufficient allowance")
50
+
51
+ s.allowance[from][msg.sender] = allowed - amount
52
+
53
+ s.balanceOf[from] -= amount
54
+ s.balanceOf[to] += amount
55
+
56
+ emit :Transfer, from: from, to: to, amount: amount
57
+
58
+ return true
59
+ end
60
+
61
+ function :_mint, { to: :address, amount: :uint256 }, :internal, :virtual do
62
+ s.totalSupply += amount
63
+ s.balanceOf[to] += amount
64
+
65
+ emit :Transfer, from: address(0), to: to, amount: amount
66
+ end
67
+
68
+ function :_burn, { from: :address, amount: :uint256 }, :internal, :virtual do
69
+ require(s.balanceOf[from] >= amount, "Insufficient balance")
70
+
71
+ s.balanceOf[from] -= amount
72
+ s.totalSupply -= amount
73
+
74
+ emit :Transfer, from: from, to: address(0), amount: amount
75
+ end
76
+ end
@@ -0,0 +1,103 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ contract :ERC721, abstract: true do
4
+ event :Transfer, { from: :address, to: :address, id: :uint256 }
5
+ event :Approval, { owner: :address, spender: :address, id: :uint256 }
6
+ event :ApprovalForAll, { owner: :address, operator: :address, approved: :bool }
7
+
8
+ string :public, :name
9
+ string :public, :symbol
10
+
11
+ mapping ({ uint256: :address }), :internal, :_ownerOf
12
+ mapping ({ address: :uint256 }), :internal, :_balanceOf
13
+
14
+ mapping ({ uint256: :address }), :public, :getApproved
15
+ mapping ({ address: mapping(address: :bool) }), :public, :isApprovedForAll
16
+
17
+ constructor(name: :string, symbol: :string) {
18
+ s.name = name
19
+ s.symbol = symbol
20
+ }
21
+
22
+ function :ownerOf, { id: :uint256 }, :public, :view, :virtual, returns: :address do
23
+ owner = s._ownerOf[id]
24
+ require(owner != address(0), "ERC721: owner query for nonexistent token")
25
+
26
+ return owner
27
+ end
28
+
29
+ function :balanceOf, { owner: :address }, :public, :view, :virtual, returns: :uint256 do
30
+ require(owner != address(0), "ERC721: balance query for nonexistent owner")
31
+
32
+ return s._balanceOf[owner]
33
+ end
34
+
35
+ function :approve, { spender: :address, id: :uint256 }, :public, :virtual do
36
+ owner = s._ownerOf[id];
37
+
38
+ require(msg.sender == owner || s.isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
39
+
40
+ s.getApproved[id] = spender;
41
+
42
+ emit :Approval, owner: owner, spender: spender, id: id
43
+ end
44
+
45
+ function :setApprovalForAll, { operator: :address, bool: :approved }, :public, :virtual do
46
+ s.isApprovedForAll[msg.sender][operator] = approved;
47
+
48
+ emit :ApprovalForAll, owner: msg.sender, operator: operator, approved: approved
49
+ end
50
+
51
+ function :transferFrom, { from: :address, to: :address, id: :uint256 }, :public, :virtual do
52
+ require(from == s._ownerOf[id], "ERC721: transfer of token that is not own");
53
+ require(to != address(0), "ERC721: transfer to the zero address");
54
+
55
+ require(
56
+ msg.sender == from ||
57
+ s.getApproved[id] == msg.sender ||
58
+ isApprovedForAll[from][msg.sender],
59
+ "NOT_AUTHORIZED"
60
+ );
61
+
62
+ s._balanceOf[from] -= 1;
63
+ s._balanceOf[to] += 1;
64
+
65
+ s._ownerOf[id] = to;
66
+
67
+ s.getApproved[id] = address(0);
68
+
69
+ return nil
70
+ end
71
+
72
+ function :_exists, { id: :uint256 }, :internal, :virtual, returns: :bool do
73
+ return s._ownerOf[id] != address(0)
74
+ end
75
+
76
+ function :_mint, { to: :address, id: :uint256 }, :internal, :virtual do
77
+ require(to != address(0), "ERC721: mint to the zero address");
78
+ require(s._ownerOf[id] == address(0), "ERC721: token already minted");
79
+
80
+ s._balanceOf[to] += 1;
81
+
82
+ s._ownerOf[id] = to;
83
+
84
+ emit :Transfer, from: address(0), to: to, id: id
85
+ end
86
+
87
+ function :_burn, { id: :uint256 }, :internal, :virtual do
88
+ owner = s._ownerOf[id];
89
+
90
+ require(owner != address(0), "ERC721: burn of nonexistent token");
91
+
92
+ s._balanceOf[owner] -= 1;
93
+
94
+ s._ownerOf[id] = address(0);
95
+
96
+ s.getApproved[id] = address(0);
97
+
98
+ emit :Transfer, from: owner, to: address(0), id: id
99
+ end
100
+
101
+ function :tokenURI, { id: :uint256 }, :public, :view, :virtual, returns: :string do
102
+ end
103
+ end
@@ -0,0 +1,115 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import "ERC20"
4
+ import "Upgradeable"
5
+
6
+ contract :EtherBridge, is: [:ERC20, :Upgradeable], upgradeable: true do
7
+ event :InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 }
8
+ event :WithdrawalComplete, { to: :address, amounts: [:uint256], withdrawalIds: [:bytes32] }
9
+
10
+ address :public, :trustedSmartContract
11
+ mapping ({ address: :uint256 }), :public, :pendingWithdrawalAmounts
12
+ mapping ({ address: array(:bytes32) }), :public, :pendingUserWithdrawalIds
13
+
14
+ bool :public, :bridgeOutPaused
15
+
16
+ constructor(
17
+ name: :string,
18
+ symbol: :string,
19
+ trustedSmartContract: :address
20
+ ) {
21
+ ERC20.constructor(name: name, symbol: symbol, decimals: 18)
22
+ Upgradeable.constructor(upgradeAdmin: msg.sender)
23
+
24
+ s.trustedSmartContract = trustedSmartContract
25
+ }
26
+
27
+ function :bridgeIn, { to: :address, amount: :uint256 }, :public do
28
+ require(
29
+ msg.sender == s.trustedSmartContract,
30
+ "Only the trusted smart contract can bridge in tokens"
31
+ )
32
+
33
+ _mint(to: to, amount: amount)
34
+ end
35
+
36
+ function :setBridgeOutPause, { newState: :bool }, :public do
37
+ require(msg.sender == s.upgradeAdmin, "Only the pause admin can pause bridge outs")
38
+
39
+ s.bridgeOutPaused = newState
40
+ nil
41
+ end
42
+
43
+ function :bridgeOut, { amount: :uint256 }, :public do
44
+ require(!s.bridgeOutPaused, "Bridge out is paused")
45
+
46
+ _burn(from: msg.sender, amount: amount)
47
+
48
+ withdrawalId = esc.currentTransactionHash
49
+
50
+ s.pendingWithdrawalAmounts[msg.sender] += amount
51
+ s.pendingUserWithdrawalIds[msg.sender].push(withdrawalId)
52
+
53
+ emit :InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId
54
+ end
55
+
56
+ function :markWithdrawalComplete, {
57
+ to: :address,
58
+ amounts: [:uint256],
59
+ withdrawalIds: [:bytes32]
60
+ }, :public do
61
+ require(
62
+ msg.sender == s.trustedSmartContract,
63
+ "Only the trusted smart contract can mark withdrawals as complete"
64
+ )
65
+
66
+ for i in 0...withdrawalIds.length
67
+ withdrawalId = withdrawalIds[i]
68
+ amount = amounts[i]
69
+
70
+ require(
71
+ s.pendingWithdrawalAmounts[to] >= amount,
72
+ "Insufficient pending withdrawal"
73
+ )
74
+
75
+ require(
76
+ _removeFirstOccurenceOfValueFromArray(
77
+ s.pendingUserWithdrawalIds[to],
78
+ withdrawalId
79
+ ),
80
+ "Withdrawal id not found"
81
+ )
82
+
83
+ s.pendingWithdrawalAmounts[to] -= amount
84
+ end
85
+
86
+ emit :WithdrawalComplete, to: to, amounts: amounts, withdrawalIds: withdrawalIds
87
+ end
88
+
89
+ function :getPendingWithdrawalsForUser, { user: :address }, :public, :view, returns: [:bytes32] do
90
+ return s.pendingUserWithdrawalIds[user]
91
+ end
92
+
93
+ function :_removeFirstOccurenceOfValueFromArray, { arr: array(:bytes32), value: :bytes32 }, :internal, returns: :bool do
94
+ for i in 0...arr.length
95
+ if arr[i] == value
96
+ return _removeItemAtIndex(arr: arr, indexToRemove: i)
97
+ end
98
+ end
99
+
100
+ return false
101
+ end
102
+
103
+ function :_removeItemAtIndex, { arr: array(:bytes32), indexToRemove: :uint256 }, :internal, returns: :bool do
104
+ lastIndex = arr.length - 1
105
+
106
+ if lastIndex != indexToRemove
107
+ lastItem = arr[lastIndex]
108
+ arr[indexToRemove] = lastItem
109
+ end
110
+
111
+ arr.pop
112
+
113
+ return true
114
+ end
115
+ end
@@ -0,0 +1,100 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import "ERC20"
4
+ import "Upgradeable"
5
+
6
+ contract :EtherBridgeV2, is: [:ERC20, :Upgradeable], upgradeable: true do
7
+ event :BridgedIn, { to: :address, amount: :uint256 }
8
+ event :InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 }
9
+ event :WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 }
10
+
11
+ address :public, :trustedSmartContract
12
+
13
+ mapping ({ address: :uint256 }), :public, :pendingWithdrawalAmounts
14
+ mapping ({ address: array(:bytes32) }), :public, :pendingUserWithdrawalIds
15
+
16
+ mapping ({ bytes32: :uint256 }), :public, :withdrawalIdAmount
17
+ mapping ({ address: :bytes32 }), :public, :userWithdrawalId
18
+
19
+ constructor(
20
+ name: :string,
21
+ symbol: :string,
22
+ trustedSmartContract: :address
23
+ ) {
24
+ require(trustedSmartContract != address(0), "Invalid smart contract")
25
+
26
+ ERC20.constructor(name: name, symbol: symbol, decimals: 18)
27
+ Upgradeable.constructor(upgradeAdmin: msg.sender)
28
+
29
+ s.trustedSmartContract = trustedSmartContract
30
+ }
31
+
32
+ function :onUpgrade, { usersToProcess: [:address] }, :public do
33
+ require(msg.sender == address(this), "Only the contract can call this function")
34
+
35
+ for i in 0...usersToProcess.length
36
+ user = usersToProcess[i]
37
+
38
+ require(s.pendingUserWithdrawalIds[user].length == 1, "Migration not possible")
39
+
40
+ withdrawalId = s.pendingUserWithdrawalIds[user].pop
41
+ amount = s.pendingWithdrawalAmounts[user]
42
+
43
+ s.pendingWithdrawalAmounts[user] = 0
44
+ s.userWithdrawalId[user] = withdrawalId
45
+
46
+ s.withdrawalIdAmount[withdrawalId] = amount
47
+ end
48
+
49
+ nil
50
+ end
51
+
52
+ function :bridgeIn, { to: :address, amount: :uint256 }, :public do
53
+ require(
54
+ msg.sender == s.trustedSmartContract,
55
+ "Only the trusted smart contract can bridge in tokens"
56
+ )
57
+
58
+ _mint(to: to, amount: amount)
59
+ emit :BridgedIn, to: to, amount: amount
60
+ end
61
+
62
+ function :bridgeOut, { amount: :uint256 }, :public do
63
+ withdrawalId = esc.currentTransactionHash
64
+ require(
65
+ s.userWithdrawalId[msg.sender] == bytes32(0),
66
+ "Withdrawal pending"
67
+ )
68
+ require(
69
+ s.withdrawalIdAmount[withdrawalId] == 0,
70
+ "Already bridged out"
71
+ )
72
+ require(amount > 0, "Invalid amount")
73
+
74
+ s.userWithdrawalId[msg.sender] = withdrawalId
75
+ s.withdrawalIdAmount[withdrawalId] = amount
76
+
77
+ _burn(from: msg.sender, amount: amount)
78
+ emit :InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId
79
+ end
80
+
81
+ function :markWithdrawalComplete, {
82
+ to: :address,
83
+ withdrawalId: :bytes32
84
+ }, :public do
85
+ require(
86
+ msg.sender == s.trustedSmartContract,
87
+ "Only the trusted smart contract can mark withdrawals as complete"
88
+ )
89
+ require(
90
+ s.userWithdrawalId[to] == withdrawalId,
91
+ "Withdrawal id not found"
92
+ )
93
+
94
+ amount = s.withdrawalIdAmount[withdrawalId]
95
+ s.withdrawalIdAmount[withdrawalId] = 0
96
+ s.userWithdrawalId[to] = bytes32(0)
97
+
98
+ emit :WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId
99
+ end
100
+ end
@@ -0,0 +1,89 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import "ERC20"
4
+ import "Upgradeable"
5
+
6
+ contract :EthscriptionERC20Bridge, is: [:ERC20, :Upgradeable], upgradeable: true do
7
+ event :BridgedIn, { to: :address, amount: :uint256 }
8
+ event :InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 }
9
+ event :WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 }
10
+
11
+ uint256 :public, :mintAmount
12
+ address :public, :trustedSmartContract
13
+
14
+ mapping ({ address: :uint256 }), :public, :bridgedInAmount
15
+ mapping ({ bytes32: :uint256 }), :public, :withdrawalIdAmount
16
+ mapping ({ address: :bytes32 }), :public, :userWithdrawalId
17
+
18
+ constructor(
19
+ name: :string,
20
+ symbol: :string,
21
+ mintAmount: :uint256,
22
+ trustedSmartContract: :address
23
+ ) {
24
+ require(mintAmount > 0, "Invalid mint amount")
25
+ require(trustedSmartContract != address(0), "Invalid smart contract")
26
+
27
+ ERC20.constructor(name: name, symbol: symbol, decimals: 18)
28
+ Upgradeable.constructor(upgradeAdmin: msg.sender)
29
+
30
+ s.mintAmount = mintAmount
31
+ s.trustedSmartContract = trustedSmartContract
32
+ }
33
+
34
+ function :bridgeIn, { to: :address, amount: :uint256 }, :public do
35
+ require(
36
+ msg.sender == s.trustedSmartContract,
37
+ "Only the trusted smart contract can bridge in tokens"
38
+ )
39
+
40
+ s.bridgedInAmount[to] += amount
41
+
42
+ _mint(to: to, amount: amount * s.mintAmount * 1.ether)
43
+ emit :BridgedIn, to: to, amount: amount
44
+ end
45
+
46
+ function :bridgeOut, { amount: :uint256 }, :public do
47
+ withdrawalId = esc.currentTransactionHash
48
+ require(
49
+ s.userWithdrawalId[msg.sender] == bytes32(0),
50
+ "Withdrawal pending"
51
+ )
52
+ require(
53
+ s.withdrawalIdAmount[withdrawalId] == 0,
54
+ "Already bridged out"
55
+ )
56
+ require(
57
+ s.bridgedInAmount[msg.sender] >= amount,
58
+ "Not enough bridged in"
59
+ )
60
+ require(amount > 0, "Invalid amount")
61
+
62
+ s.userWithdrawalId[msg.sender] = withdrawalId
63
+ s.withdrawalIdAmount[withdrawalId] = amount
64
+ s.bridgedInAmount[msg.sender] -= amount
65
+
66
+ _burn(from: msg.sender, amount: amount * s.mintAmount * 1.ether)
67
+ emit :InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId
68
+ end
69
+
70
+ function :markWithdrawalComplete, {
71
+ to: :address,
72
+ withdrawalId: :bytes32
73
+ }, :public do
74
+ require(
75
+ msg.sender == s.trustedSmartContract,
76
+ "Only the trusted smart contract can mark withdrawals as complete"
77
+ )
78
+ require(
79
+ s.userWithdrawalId[to] == withdrawalId,
80
+ "Withdrawal id not found"
81
+ )
82
+
83
+ amount = s.withdrawalIdAmount[withdrawalId]
84
+ s.withdrawalIdAmount[withdrawalId] = 0
85
+ s.userWithdrawalId[to] = bytes32(0)
86
+
87
+ emit :WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId
88
+ end
89
+ end
@@ -0,0 +1,95 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import 'ERC721'
4
+
5
+ contract :GenerativeERC721, is: :ERC721 do
6
+ string :public, :generativeScript
7
+ mapping ({ uint256: :uint256 }), :public, :tokenIdToSeed
8
+
9
+ uint256 :public, :totalSupply
10
+ uint256 :public, :maxSupply
11
+ uint256 :public, :maxPerAddress
12
+ string :public, :description
13
+
14
+ constructor(
15
+ name: :string,
16
+ symbol: :string,
17
+ generativeScript: :string,
18
+ maxSupply: :uint256,
19
+ description: :string,
20
+ maxPerAddress: :uint256
21
+ ) {
22
+ ERC721.constructor(name: name, symbol: symbol)
23
+
24
+ s.maxSupply = maxSupply
25
+ s.maxPerAddress = maxPerAddress
26
+ s.description = description
27
+ s.generativeScript = generativeScript
28
+ }
29
+
30
+ function :mint, { amount: :uint256 }, :public, returns: :uint256 do
31
+ require(amount > 0, 'Amount must be positive')
32
+ require(amount + s._balanceOf[msg.sender] <= s.maxPerAddress, 'Exceeded mint limit')
33
+ require(amount + s.totalSupply <= s.maxSupply, 'Exceeded max supply')
34
+
35
+ hash = blockhash(block.number).cast(:uint256) % (2 ** 48)
36
+
37
+ amount.times do |id|
38
+ tokenId = s.totalSupply + id
39
+ seed = hash + tokenId
40
+
41
+ s.tokenIdToSeed[tokenId] = seed
42
+
43
+ _mint(to: msg.sender, id: tokenId)
44
+ end
45
+
46
+ s.totalSupply += amount
47
+ end
48
+
49
+ function :tokenURI, { id: :uint256 }, :public, :view, :override, returns: :string do
50
+ require(_exists(id: id), 'ERC721Metadata: URI query for nonexistent token')
51
+
52
+ html = getHTML(seed: s.tokenIdToSeed[id])
53
+
54
+ html_as_base_64_data_uri = "data:text/html;base64," + esc.base64Encode(html)
55
+
56
+ json_data = {
57
+ name: "#{s.name} ##{string(id)}",
58
+ description: s.description,
59
+ animation_url: html_as_base_64_data_uri,
60
+ }.to_json
61
+
62
+ return "data:application/json,#{json_data}"
63
+ end
64
+
65
+ function :getHTML, { seed: :uint256 }, :public, :view, returns: :string do
66
+ <<~HTML
67
+ <html>
68
+ <head>
69
+ <style>
70
+ body,
71
+ html {
72
+ width: 100%;
73
+ height: 100%;
74
+ margin: 0;
75
+ padding: 0;
76
+ overflow: hidden;
77
+ display: block;
78
+ }
79
+
80
+ #canvas {
81
+ position: absolute;
82
+ }
83
+ </style>
84
+ </head>
85
+ <body>
86
+ <canvas id="canvas"></canvas>
87
+ </body>
88
+ <script>
89
+ window.SEED = #{string(seed)};
90
+ #{s.generativeScript}
91
+ </script>
92
+ </html>
93
+ HTML
94
+ end
95
+ end
@@ -0,0 +1,56 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import 'ERC721'
4
+
5
+ contract :OpenEditionERC721, is: :ERC721 do
6
+ string :public, :contentURI
7
+ uint256 :public, :maxPerAddress
8
+ uint256 :public, :totalSupply
9
+ string :public, :description
10
+
11
+ datetime :public, :mintStart
12
+ datetime :public, :mintEnd
13
+
14
+ constructor(
15
+ name: :string,
16
+ symbol: :string,
17
+ contentURI: :string,
18
+ maxPerAddress: :uint256,
19
+ description: :string,
20
+ mintStart: :datetime,
21
+ mintEnd: :datetime
22
+ ) {
23
+ ERC721.constructor(name: name, symbol: symbol)
24
+
25
+ s.maxPerAddress = maxPerAddress
26
+ s.description = description
27
+ s.contentURI = contentURI
28
+ s.mintStart = mintStart
29
+ s.mintEnd = mintEnd
30
+ }
31
+
32
+ function :mint, { amount: :uint256 }, :public, returns: :uint256 do
33
+ require(amount > 0, 'Amount must be positive')
34
+ require(amount + s._balanceOf[msg.sender] <= s.maxPerAddress, 'Exceeded mint limit')
35
+ require(block.timestamp >= s.mintStart, 'Minting has not started')
36
+ require(block.timestamp < s.mintEnd, 'Minting has ended')
37
+
38
+ amount.times do |id|
39
+ _mint(to: msg.sender, id: s.totalSupply + id)
40
+ end
41
+
42
+ s.totalSupply += amount
43
+ end
44
+
45
+ function :tokenURI, { id: :uint256 }, :public, :view, :override, returns: :string do
46
+ require(_exists(id: id), 'ERC721Metadata: URI query for nonexistent token')
47
+
48
+ json_data = {
49
+ name: "#{s.name} ##{string(id)}",
50
+ description: s.description,
51
+ image: s.contentURI,
52
+ }.to_json
53
+
54
+ return "data:application/json,#{json_data}"
55
+ end
56
+ end
@@ -0,0 +1,38 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import 'ERC20'
4
+
5
+ contract :PublicMintERC20, is: :ERC20 do
6
+ uint256 :public, :maxSupply
7
+ uint256 :public, :perMintLimit
8
+
9
+ constructor(
10
+ name: :string,
11
+ symbol: :string,
12
+ maxSupply: :uint256,
13
+ perMintLimit: :uint256,
14
+ decimals: :uint8
15
+ ) {
16
+ ERC20.constructor(name: name, symbol: symbol, decimals: decimals)
17
+ s.maxSupply = maxSupply
18
+ s.perMintLimit = perMintLimit
19
+ }
20
+
21
+ function :mint, { amount: :uint256 }, :public do
22
+ require(amount > 0, 'Amount must be positive')
23
+ require(amount <= s.perMintLimit, 'Exceeded mint limit')
24
+
25
+ require(s.totalSupply + amount <= s.maxSupply, 'Exceeded max supply')
26
+
27
+ _mint(to: msg.sender, amount: amount)
28
+ end
29
+
30
+ function :airdrop, { to: :address, amount: :uint256 }, :public do
31
+ require(amount > 0, 'Amount must be positive')
32
+ require(amount <= s.perMintLimit, 'Exceeded mint limit')
33
+
34
+ require(s.totalSupply + amount <= s.maxSupply, 'Exceeded max supply')
35
+
36
+ _mint(to: to, amount: amount)
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ import 'ERC20'
4
+
5
+ contract :UnsafeNoApprovalERC20, is: :ERC20 do
6
+ constructor(
7
+ name: :string,
8
+ symbol: :string,
9
+ ) {
10
+ ERC20.constructor(name: name, symbol: symbol, decimals: 18)
11
+ }
12
+
13
+ function :mint, { amount: :uint256 }, :public do
14
+ require(amount > 0, 'Amount must be positive')
15
+
16
+ _mint(to: msg.sender, amount: amount)
17
+ end
18
+
19
+ function :airdrop, { to: :address, amount: :uint256 }, :public do
20
+ require(amount > 0, 'Amount must be positive')
21
+
22
+ _mint(to: to, amount: amount)
23
+ end
24
+
25
+ function :transferFrom, {
26
+ from: :address,
27
+ to: :address,
28
+ amount: :uint256
29
+ }, :public, :override, returns: :bool do
30
+ require(s.balanceOf[from] >= amount, 'Insufficient balance')
31
+
32
+ s.balanceOf[from] -= amount
33
+ s.balanceOf[to] += amount
34
+
35
+ emit :Transfer, from: from, to: to, amount: amount
36
+
37
+ return true
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ pragma :rubidity, "1.0.0"
2
+
3
+ contract :Upgradeable, abstract: true do
4
+ address :public, :upgradeAdmin
5
+
6
+ event :ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 }
7
+ event :UpgradeAdminChanged, { newUpgradeAdmin: :address }
8
+
9
+ constructor(upgradeAdmin: :address) {
10
+ s.upgradeAdmin = upgradeAdmin
11
+ }
12
+
13
+ function :setUpgradeAdmin, { newUpgradeAdmin: :address }, :public do
14
+ require(msg.sender == s.upgradeAdmin, "NOT_AUTHORIZED")
15
+
16
+ s.upgradeAdmin = newUpgradeAdmin
17
+
18
+ emit :UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin
19
+ end
20
+
21
+ function :upgradeAndCall, { newHash: :bytes32, migrationCalldata: :string }, :public do
22
+ upgrade(newHash: newHash)
23
+
24
+ (success, data) = address(this).call(migrationCalldata)
25
+ require(success, "Migration failed")
26
+ end
27
+
28
+ function :upgrade, { newHash: :bytes32 }, :public do
29
+ currentHash = esc.getImplementationHash
30
+
31
+ require(msg.sender == s.upgradeAdmin, "NOT_AUTHORIZED")
32
+
33
+ esc.upgradeContract(newHash)
34
+
35
+ emit :ContractUpgraded, oldHash: currentHash, newHash: newHash
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+
2
+
3
+ puts "hello, 0xfacet contracts!"
4
+
5
+ # note: cannot load rubidity contracts as is - require rubidity loader!
6
+
7
+
8
+
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: 0xfacet-contracts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gerald Bauer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: 0xfacet-rubidity
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rdoc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '7'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '4.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '7'
47
+ - !ruby/object:Gem::Dependency
48
+ name: hoe
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '4.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '4.0'
61
+ description: 0xfacet-contracts - rubidity o.g. standard contracts (incl. ERC20, PublicMintERC20,
62
+ ERC721, GenerativeERC721, etc.)
63
+ email: gerald.bauer@gmail.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files:
67
+ - CHANGELOG.md
68
+ - Manifest.txt
69
+ - README.md
70
+ files:
71
+ - CHANGELOG.md
72
+ - Manifest.txt
73
+ - README.md
74
+ - Rakefile
75
+ - lib/0xfacet/contracts.rb
76
+ - lib/0xfacet/contracts/ERC20.rb
77
+ - lib/0xfacet/contracts/ERC721.rb
78
+ - lib/0xfacet/contracts/EtherBridge.rb
79
+ - lib/0xfacet/contracts/EtherBridgeV2.rb
80
+ - lib/0xfacet/contracts/EthscriptionERC20Bridge.rb
81
+ - lib/0xfacet/contracts/GenerativeERC721.rb
82
+ - lib/0xfacet/contracts/OpenEditionERC721.rb
83
+ - lib/0xfacet/contracts/PublicMintERC20.rb
84
+ - lib/0xfacet/contracts/UnsafeNoApprovalERC20.rb
85
+ - lib/0xfacet/contracts/Upgradeable.rb
86
+ homepage: https://github.com/s6ruby/rubidity.review
87
+ licenses:
88
+ - Public Domain
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options:
92
+ - "--main"
93
+ - README.md
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '2.3'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubygems_version: 3.4.10
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: 0xfacet-contracts - rubidity o.g. standard contracts (incl. ERC20, PublicMintERC20,
111
+ ERC721, GenerativeERC721, etc.)
112
+ test_files: []