diff --git a/lib/hive.rb b/lib/hive.rb
index ccae1be4d033ade7710097e4cdea9a00247b0e46..c90e41b58badc20a8e33d8cb25d222ce6b5444d5 100644
--- a/lib/hive.rb
+++ b/lib/hive.rb
@@ -16,6 +16,7 @@ require 'hive/operation'
 require 'hive/operation/account_create.rb'
 require 'hive/operation/account_create_with_delegation.rb'
 require 'hive/operation/account_update.rb'
+require 'hive/operation/account_update2.rb'
 require 'hive/operation/account_witness_proxy.rb'
 require 'hive/operation/account_witness_vote.rb'
 require 'hive/operation/cancel_transfer_from_savings.rb'
@@ -27,6 +28,7 @@ require 'hive/operation/comment.rb'
 require 'hive/operation/comment_options.rb'
 require 'hive/operation/convert.rb'
 require 'hive/operation/create_claimed_account.rb'
+require 'hive/operation/create_proposal.rb'
 require 'hive/operation/custom.rb'
 require 'hive/operation/custom_binary.rb'
 require 'hive/operation/custom_json.rb'
@@ -43,6 +45,7 @@ require 'hive/operation/limit_order_create.rb'
 require 'hive/operation/limit_order_create2.rb'
 require 'hive/operation/prove_authority.rb'
 require 'hive/operation/recover_account.rb'
+require 'hive/operation/remove_proposal.rb'
 require 'hive/operation/report_over_production.rb'
 require 'hive/operation/request_account_recovery.rb'
 require 'hive/operation/reset_account.rb'
@@ -52,6 +55,7 @@ require 'hive/operation/transfer.rb'
 require 'hive/operation/transfer_from_savings.rb'
 require 'hive/operation/transfer_to_savings.rb'
 require 'hive/operation/transfer_to_vesting.rb'
+require 'hive/operation/update_proposal_votes.rb'
 require 'hive/operation/vote.rb'
 require 'hive/operation/withdraw_vesting.rb'
 require 'hive/operation/witness_update.rb'
diff --git a/lib/hive/broadcast.rb b/lib/hive/broadcast.rb
index d9a8af7ea1a8da7a8adb4a2047003278f0dc8f47..b5f85da8adb25b5dfd9471837330b43e59400439 100644
--- a/lib/hive/broadcast.rb
+++ b/lib/hive/broadcast.rb
@@ -1237,7 +1237,124 @@ module Hive
       
       process(options.merge(ops: ops), &block)
     end
-        
+    
+    # @param options [Hash] options
+    # @option options [String] :wif Posting wif
+    # @option options [Hash] :params
+    #   * :account (String) Account claiming rewards.
+    #   * :reward_steem (Amount) Amount of HIVE to claim.
+    #   * :reward_sbd (Amount) Amount of HBD to claim.
+    #   * :reward_vests (Amount) Amount of VESTS to claim.
+    # @option options [Boolean] :pretend Just validate, do not broadcast.
+    # @see https://developers.hive.io/apidefinitions/broadcast-ops.html#broadcast_ops_claim_reward_balance
+    def self.claim_reward_balance(options, &block)
+      required_fields = %i(account)
+      params = options[:params]
+      
+      check_required_fields(params, *required_fields)
+      
+      params[:reward_steem] = normalize_amount(options.merge amount: params[:reward_steem])
+      params[:reward_sbd] = normalize_amount(options.merge amount: params[:reward_sbd])
+      params[:reward_vests] = normalize_amount(options.merge amount: params[:reward_vests])
+      
+      ops = [[:claim_reward_balance, params]]
+      
+      process(options.merge(ops: ops), &block)
+    end
+    
+    # @param options [Hash] options
+    # @option options [String] :wif Active wif
+    # @option options [Hash] :params
+    #   * :account (String) Account being updated.
+    #   * :metadata (Hash) Metadata of the account, becomes `json_metadata`.
+    #   * :json_metadata (String) String version of `metadata` (use one or the other).
+    # @option options [Boolean] :pretend Just validate, do not broadcast.
+    # @see https://developers.hive.io/apidefinitions/broadcast-ops.html#broadcast_ops_account_update2
+    def self.account_update2(options, &block)
+      required_fields = %i(account)
+      params = options[:params]
+      
+      check_required_fields(params, *required_fields)
+      
+      if !!params[:metadata] && !!params[:json_metadata]
+        raise Hive::ArgumentError, 'Assign either metadata or json_metadata, not both.'
+      end
+      
+      metadata = params.delete(:metadata) || {}
+      metadata ||= (JSON[params[:json_metadata]] || nil) || {}
+      params[:json_metadata] = metadata.to_json
+      
+      ops = [[:account_update2, params]]
+      
+      process(options.merge(ops: ops), &block)
+    end
+    
+    # @param options [Hash] options
+    # @option options [String] :wif Active wif
+    # @option options [Hash] :params
+    #   * :creator (String) Creator of the new proposal.
+    #   * :receiver (String) Reciever of `daily_pay` (or creator if empty)
+    #   * :start_date (String) When the proposal starts.
+    #   * :end_date (String) When the proposal ends.
+    #   * :daily_pay (String) Daily pay in HBD starting on the `start_date` and ending on the `end_date`.
+    #   * :subject (String) Subject of the proposal.
+    #   * :permlink (String) Proposal permlink must point to the article posted by creator or receiver.
+    # @option options [Boolean] :pretend Just validate, do not broadcast.
+    # @see https://developers.hive.io/apidefinitions/broadcast-ops.html#broadcast_ops_create_proposal
+    def self.create_proposal(options, &block)
+      required_fields = %i(creator start_date end_date daily_pay subject permlink)
+      params = options[:params]
+      
+      check_required_fields(params, *required_fields)
+      
+      params[:start_date] = Time.parse(params[:start_date].to_s)
+      params[:start_date] = params[:start_date].strftime('%Y-%m-%dT%H:%M:%S')
+      params[:end_date] = Time.parse(params[:end_date].to_s)
+      params[:end_date] = params[:end_date].strftime('%Y-%m-%dT%H:%M:%S')
+      params[:daily_pay] = normalize_amount(options.merge amount: params[:daily_pay])
+      
+      ops = [[:create_proposal, params]]
+      
+      process(options.merge(ops: ops), &block)
+    end
+    
+    # @param options [Hash] options
+    # @option options [String] :wif Active wif
+    # @option options [Hash] :params
+    #   * :voter (String) Account doing approval (or removing approval).
+    #   * :proposal_ids (Array<Integer>) Proposals to approve (or remove approval) for.
+    #   * :approve (Boolean) Approve or unapprove.
+    # @option options [Boolean] :pretend Just validate, do not broadcast.
+    # @see https://developers.hive.io/apidefinitions/broadcast-ops.html#broadcast_ops_update_proposal_votes
+    def self.update_proposal_votes(options, &block)
+      required_fields = %i(voter proposal_ids approve)
+      params = options[:params]
+      
+      check_required_fields(params, *required_fields)
+      
+      ops = [[:update_proposal_votes, params]]
+      
+      process(options.merge(ops: ops), &block)
+    end
+    
+    # @param options [Hash] options
+    # @option options [String] :wif Active wif
+    # @option options [Hash] :params
+    #   * :proposal_owner (String) Creator of the proposal.
+    #   * :proposal_ids (Array<Integer>) Proposals to remove.
+    # @option options [Boolean] :pretend Just validate, do not broadcast.
+    # @see https://developers.hive.io/apidefinitions/broadcast-ops.html#broadcast_ops_update_proposal_votes
+    def self.remove_proposal(options, &block)
+      required_fields = %i(proposal_owner proposal_ids)
+      params = options[:params]
+      
+      check_required_fields(params, *required_fields)
+      
+      ops = [[:remove_proposal, params]]
+      
+      process(options.merge(ops: ops), &block)
+    end
+    
     # @param options [Hash] options
     # @option options [Array<Array<Hash>] :ops Operations to process.
     # @option options [Boolean] :pretend Just validate, do not broadcast.
diff --git a/lib/hive/operation.rb b/lib/hive/operation.rb
index 4f7b8510900dbb726b2e20c9f791255fcf450750..5719546b9923a34097d9eaa7c436761136db047b 100644
--- a/lib/hive/operation.rb
+++ b/lib/hive/operation.rb
@@ -5,7 +5,7 @@ module Hive
     include Utils
     
     # IDs derrived from:
-    # https://github.com/openhive-network/hive/blob/127a441fbac2f06804359968bda83b66e602c891/libraries/protocol/include/steem/protocol/operations.hpp
+    # https://gitlab.syncad.com/hive/hive/-/blob/master/libraries/protocol/include/steem/protocol/operations.hpp
     
     IDS = [
       :vote_operation,
@@ -60,6 +60,10 @@ module Hive
       :delegate_vesting_shares_operation,
       :account_create_with_delegation_operation,
       :witness_set_properties_operation,
+      :account_update2_operation,
+      :create_proposal_operation,
+      :update_proposal_votes_operation,
+      :remove_proposal_operation,
       
       # SMT operations
       :claim_reward_balance2_operation,
diff --git a/lib/hive/operation/account_update2.rb b/lib/hive/operation/account_update2.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d6538c571bb5c8894ab02686ddfd0ab21d969211
--- /dev/null
+++ b/lib/hive/operation/account_update2.rb
@@ -0,0 +1,4 @@
+class Hive::Operation::AccountUpdate2 < Hive::Operation
+  def_attr account: :string
+  def_attr json_metadata: :string
+end
diff --git a/lib/hive/operation/create_proposal.rb b/lib/hive/operation/create_proposal.rb
new file mode 100644
index 0000000000000000000000000000000000000000..171e71f35d735faaa206df25922f63a0b6c3bdbb
--- /dev/null
+++ b/lib/hive/operation/create_proposal.rb
@@ -0,0 +1,9 @@
+class Hive::Operation::CreateProposal < Hive::Operation
+  def_attr creator: :string
+  def_attr receiver: :string
+  def_attr start_date: :point_in_time
+  def_attr end_date: :point_in_time
+  def_attr daily_pay: :amount
+  def_attr subject: :string
+  def_attr permlink: :string
+end
diff --git a/lib/hive/operation/remove_proposal.rb b/lib/hive/operation/remove_proposal.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4abd441e0e0aa8ddc7c4619414d5263c2e992dc1
--- /dev/null
+++ b/lib/hive/operation/remove_proposal.rb
@@ -0,0 +1,4 @@
+class Hive::Operation::RemoveProposal < Hive::Operation
+  def_attr proposal_owner: :string
+  def_attr proposal_ids: :uint64_array
+end
diff --git a/lib/hive/operation/update_proposal_votes.rb b/lib/hive/operation/update_proposal_votes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ed9885e47a3ec0ac6dff561f52e8bc9e618d8660
--- /dev/null
+++ b/lib/hive/operation/update_proposal_votes.rb
@@ -0,0 +1,5 @@
+class Hive::Operation::UpdateProposalVotes < Hive::Operation
+  def_attr voter: :string
+  def_attr proposal_ids: :uint64_array
+  def_attr approve: :boolean
+end
diff --git a/test/hive/broadcast_test.rb b/test/hive/broadcast_test.rb
index 08af1fa0671d2c17012b25c61d7900b3929e6330..de0b59ab957f92185e3933bddb7b19b1f0828caf 100644
--- a/test/hive/broadcast_test.rb
+++ b/test/hive/broadcast_test.rb
@@ -9,7 +9,8 @@ module Hive
       feed_publish limit_order_cancel limit_order_create recover_account
       request_account_recovery set_withdraw_vesting_route transfer
       transfer_to_vesting vote withdraw_vesting witness_update
-      witness_set_properties create_claimed_account claim_account)
+      witness_set_properties create_claimed_account claim_account
+      claim_reward_balance)
     
     def setup
       app_base = false # todo: randomly set true or false to test differences.
@@ -648,7 +649,7 @@ module Hive
           props: {
             account_creation_fee: "0.000 #{@core_symbol}",
             maximum_block_size: 131072,
-            sbd_interest_rate:1000
+            sbd_interest_rate: 1000
           },
           fee: "0.000 #{@core_symbol}"
         }
@@ -761,7 +762,7 @@ module Hive
           id: 777,
           data: '0a627974656d617374657207737465656d697402a3d13897d82114466ad87a74b73a53292d8331d1bd1d3082da6bfbcff19ed097029db013797711c88cccca3692407f9ff9b9ce7221aaa2d797f1692be2215d0a5f6d2a8cab6832050078bc5729201e3ea24ea9f7873e6dbdc65a6bd9899053b9acda876dc69f11a13df9ca8b26b6'
         },
-        force_serialize: true # FIXME
+        force_serialize: @force_serialize
       }
     
       vcr_cassette('broadcast_custom') do
@@ -777,7 +778,7 @@ module Hive
           id: 777,
           data: '0a627974656d617374657207737465656d697402a3d13897d82114466ad87a74b73a53292d8331d1bd1d3082da6bfbcff19ed097029db013797711c88cccca3692407f9ff9b9ce7221aaa2d797f1692be2215d0a5f6d2a8cab6832050078bc5729201e3ea24ea9f7873e6dbdc65a6bd9899053b9acda876dc69f11a13df9ca8b26b6'
         },
-        force_serialize: true # FIXME
+        force_serialize: @force_serialize
       }
     
       vcr_cassette('broadcast_custom_binary') do
@@ -1157,6 +1158,127 @@ module Hive
       end
     end
     
+    def test_claim_reward_balance
+      options = {
+        params: {
+          account: @account_name,
+          reward_steem: "0.000 #{@core_symbol}",
+          reward_sbd: "0.000 #{@debt_symbol}",
+          reward_vests: "0.000000 #{@vest_symbol}"
+        }
+      }
+    
+      vcr_cassette('broadcast_claim_reward_balance') do
+        assert Broadcast.claim_reward_balance(@broadcast_options.merge(options))
+      end
+    end
+    
+    def test_account_update2
+      options = {
+        params: {
+          account: @account_name,
+          json_metadata: '{}'
+        }
+      }
+      
+      vcr_cassette('broadcast_account_update2') do
+        assert_raises MissingActiveAuthorityError do
+          Broadcast.account_update2(@broadcast_options.merge(options))
+        end
+      end
+    end
+    
+    def test_account_update2_both_metadata
+      options = {
+        params: {
+          metadata: {},
+          json_metadata: '{}'
+        }
+      }
+      
+      assert_raises Hive::ArgumentError do
+        Broadcast.account_update2(@broadcast_options.merge(options))
+      end
+    end
+    
+    def test_account_update2_empty
+      options = {
+        params: {
+          account: @account_name,
+          json_metadata: '{}'
+        }
+      }
+      
+      vcr_cassette('broadcast_account_update_empty') do
+        assert_raises MissingActiveAuthorityError do
+          Broadcast.account_update2(@broadcast_options.merge(options))
+        end
+      end
+    end
+    
+    def test_create_proposal
+      options = {
+        params: {
+          creator: @account_name,
+          receiver: '',
+          start_date: (Time.now.utc + 300),
+          end_date: (Time.now.utc + 900),
+          daily_pay: "0.000 #{@debt_symbol}",
+          subject: 'subject',
+          permlink: 'permlink'
+        }
+      }
+      
+      vcr_cassette('broadcast_create_proposal') do
+        assert_raises MissingActiveAuthorityError do
+          Broadcast.create_proposal(@broadcast_options.merge(options))
+        end
+      end
+    end
+    
+    def test_update_proposal_votes
+      options = {
+        params: {
+          voter: @account_name,
+          proposal_ids: ['1'],
+          approve: true
+        }
+      }
+      
+      vcr_cassette('broadcast_update_proposal_votes') do
+        assert_raises MissingActiveAuthorityError do
+          Broadcast.update_proposal_votes(@broadcast_options.merge(options))
+        end
+      end
+    end
+    
+    def test_remove_proposal
+      options = {
+        params: {
+          proposal_owner: @account_name,
+          proposal_ids: ['1']
+        }
+      }
+      
+      vcr_cassette('broadcast_remove_proposal') do
+        assert_raises MissingActiveAuthorityError do
+          Broadcast.remove_proposal(@broadcast_options.merge(options))
+        end
+      end
+    end
+    
+    def test_fake_op
+      options = {
+        ops: [[:bogus, {}]]
+      }
+      
+      vcr_cassette('broadcast_fake_op') do
+        assert_raises UnknownOperationError do
+          Hive::Broadcast.process(@broadcast_options.merge(options))
+        end
+      end
+    end
+    
     # This test picks a random op to try.
     def test_random_op
       fields = %i(account account_to_recover active agent allow_curation_rewards